diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..5facbdfb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*.{kt,kts}] +ktlint_function_naming_ignore_when_annotated_with=Composable diff --git a/build.gradle.kts b/build.gradle.kts index 3f98de27..bcaddfe5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ buildscript { classpath("com.android.tools.build:gradle:8.0.2") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Constants.kotlinVersion}") classpath("com.github.dcendents:android-maven-gradle-plugin:2.1") - classpath("com.diffplug.spotless:spotless-plugin-gradle:5.14.2") + classpath("com.diffplug.spotless:spotless-plugin-gradle:6.23.3") classpath("io.github.gradle-nexus:publish-plugin:1.3.0") classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.7.0") } diff --git a/konfetti/compose/build.gradle.kts b/konfetti/compose/build.gradle.kts index 84829e58..1f07a7fd 100644 --- a/konfetti/compose/build.gradle.kts +++ b/konfetti/compose/build.gradle.kts @@ -9,12 +9,12 @@ apply(from = "../../scripts/publish-module.gradle.kts") spotless { kotlin { - ktlint("0.37.2") + ktlint("1.1.0") target("src/**/*.kt") } java { removeUnusedImports() - googleJavaFormat("1.5") + googleJavaFormat("1.15.0") target("**/*.java") } } diff --git a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/DrawShapes.kt b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/DrawShapes.kt index 67f0cadc..b711d8b6 100644 --- a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/DrawShapes.kt +++ b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/DrawShapes.kt @@ -25,14 +25,19 @@ import nl.dionsegijn.konfetti.xml.image.ImageStore * `size` and must vertically/horizontally center their asset if it does not have an equal width * and height. */ -fun Shape.draw(drawScope: DrawScope, particle: Particle, imageResource: ImageBitmap? = null, imageStore: ImageStore) { +fun Shape.draw( + drawScope: DrawScope, + particle: Particle, + imageResource: ImageBitmap? = null, + imageStore: ImageStore, +) { when (this) { Circle -> { val offsetMiddle = particle.width / 2 drawScope.drawCircle( color = Color(particle.color), center = Offset(particle.x + offsetMiddle, particle.y + offsetMiddle), - radius = particle.width / 2 + radius = particle.width / 2, ) } Square -> { @@ -48,7 +53,7 @@ fun Shape.draw(drawScope: DrawScope, particle: Particle, imageResource: ImageBit drawScope.drawRect( color = Color(particle.color), topLeft = Offset(particle.x, particle.y), - size = Size(size, height) + size = Size(size, height), ) } is DrawableShape -> { diff --git a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/KonfettiView.kt b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/KonfettiView.kt index b55f7cd4..68395f10 100644 --- a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/KonfettiView.kt +++ b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/KonfettiView.kt @@ -25,9 +25,8 @@ import nl.dionsegijn.konfetti.xml.image.ImageStore fun KonfettiView( modifier: Modifier = Modifier, parties: List, - updateListener: OnParticleSystemUpdateListener? = null + updateListener: OnParticleSystemUpdateListener? = null, ) { - lateinit var partySystems: List /** @@ -51,63 +50,67 @@ fun KonfettiView( val imageStore = remember { ImageStore() } LaunchedEffect(Unit) { - partySystems = parties.map { - PartySystem( - party = storeImages(it, imageStore), - pixelDensity = Resources.getSystem().displayMetrics.density - ) - } + partySystems = + parties.map { + PartySystem( + party = storeImages(it, imageStore), + pixelDensity = Resources.getSystem().displayMetrics.density, + ) + } while (true) { withFrameMillis { frameMs -> // Calculate time between frames, fallback to 0 when previous frame doesn't exist val deltaMs = if (frameTime.value > 0) (frameMs - frameTime.value) else 0 frameTime.value = frameMs - particles.value = partySystems.map { particleSystem -> + particles.value = + partySystems.map { particleSystem -> - val totalTimeRunning = getTotalTimeRunning(particleSystem.createdAt) - // Do not start particleSystem yet if totalTimeRunning is below delay - if (totalTimeRunning < particleSystem.party.delay) return@map listOf() + val totalTimeRunning = getTotalTimeRunning(particleSystem.createdAt) + // Do not start particleSystem yet if totalTimeRunning is below delay + if (totalTimeRunning < particleSystem.party.delay) return@map listOf() - if (particleSystem.isDoneEmitting()) { - updateListener?.onParticleSystemEnded( - system = particleSystem, - activeSystems = partySystems.count { !it.isDoneEmitting() } - ) - } + if (particleSystem.isDoneEmitting()) { + updateListener?.onParticleSystemEnded( + system = particleSystem, + activeSystems = partySystems.count { !it.isDoneEmitting() }, + ) + } - particleSystem.render(deltaMs.div(1000f), drawArea.value) - }.flatten() + particleSystem.render(deltaMs.div(1000f), drawArea.value) + }.flatten() } } } Canvas( - modifier = modifier - .onGloballyPositioned { - drawArea.value = - CoreRectImpl(0f, 0f, it.size.width.toFloat(), it.size.height.toFloat()) - }, + modifier = + modifier + .onGloballyPositioned { + drawArea.value = + CoreRectImpl(0f, 0f, it.size.width.toFloat(), it.size.height.toFloat()) + }, onDraw = { particles.value.forEach { particle -> withTransform({ rotate( degrees = particle.rotation, - pivot = Offset( - x = particle.x + (particle.width / 2), - y = particle.y + (particle.height / 2) - ) + pivot = + Offset( + x = particle.x + (particle.width / 2), + y = particle.y + (particle.height / 2), + ), ) scale( scaleX = particle.scaleX, scaleY = 1f, - pivot = Offset(particle.x + (particle.width / 2), particle.y) + pivot = Offset(particle.x + (particle.width / 2), particle.y), ) }) { particle.shape.draw(drawScope = this, particle = particle, imageStore = imageStore) } } - } + }, ) } @@ -118,16 +121,20 @@ fun KonfettiView( * @param party The Party object containing the shapes to be transformed. * @return A new Party object with the transformed shapes. */ -fun storeImages(party: Party, imageStore: ImageStore): Party { - val transformedShapes = party.shapes.map { shape -> - when (shape) { - is Shape.DrawableShape -> { - val referenceImage = drawableToReferenceImage(shape.image as DrawableImage, imageStore) - shape.copy(image = referenceImage) +fun storeImages( + party: Party, + imageStore: ImageStore, +): Party { + val transformedShapes = + party.shapes.map { shape -> + when (shape) { + is Shape.DrawableShape -> { + val referenceImage = drawableToReferenceImage(shape.image as DrawableImage, imageStore) + shape.copy(image = referenceImage) + } + else -> shape } - else -> shape } - } return party.copy(shapes = transformedShapes) } @@ -137,7 +144,10 @@ fun storeImages(party: Party, imageStore: ImageStore): Party { * @param drawableImage The DrawableImage to be converted. * @return A ReferenceImage with the same dimensions as the DrawableImage and a reference to the stored Drawable. */ -fun drawableToReferenceImage(drawableImage: DrawableImage, imageStore: ImageStore): ReferenceImage { +fun drawableToReferenceImage( + drawableImage: DrawableImage, + imageStore: ImageStore, +): ReferenceImage { val id = imageStore.storeImage(drawableImage.drawable) return ReferenceImage(id, drawableImage.width, drawableImage.height) } diff --git a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/OnParticleSystemUpdateListener.kt b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/OnParticleSystemUpdateListener.kt index c198a796..9d239084 100644 --- a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/OnParticleSystemUpdateListener.kt +++ b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/OnParticleSystemUpdateListener.kt @@ -3,5 +3,8 @@ package nl.dionsegijn.konfetti.compose import nl.dionsegijn.konfetti.core.PartySystem interface OnParticleSystemUpdateListener { - fun onParticleSystemEnded(system: PartySystem, activeSystems: Int) + fun onParticleSystemEnded( + system: PartySystem, + activeSystems: Int, + ) } diff --git a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/DrawableImage.kt b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/DrawableImage.kt index 1e38a9fc..efcf36ce 100644 --- a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/DrawableImage.kt +++ b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/DrawableImage.kt @@ -6,5 +6,5 @@ import nl.dionsegijn.konfetti.core.models.CoreImage data class DrawableImage( val drawable: Drawable, override val width: Int, - override val height: Int + override val height: Int, ) : CoreImage diff --git a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/ImageUtil.kt b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/ImageUtil.kt index f49300d0..31c2b7ff 100644 --- a/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/ImageUtil.kt +++ b/konfetti/compose/src/main/java/nl/dionsegijn/konfetti/compose/image/ImageUtil.kt @@ -4,12 +4,11 @@ import android.graphics.drawable.Drawable import nl.dionsegijn.konfetti.core.models.Shape object ImageUtil { - @JvmStatic fun loadDrawable( drawable: Drawable, tint: Boolean = true, - applyAlpha: Boolean = true + applyAlpha: Boolean = true, ): Shape.DrawableShape { val width = drawable.intrinsicWidth val height = drawable.intrinsicHeight diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/Party.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/Party.kt index f0495546..79b04bca 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/Party.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/Party.kt @@ -29,7 +29,7 @@ import nl.dionsegijn.konfetti.core.models.Size * it will slowly fade out. If set to falls it will instantly disappear from the screen. * @property position the point where the confetti will spawn relative to the canvas. Use absolute * coordinates with [Position.Absolute] or relative coordinates between 0.0 and 1.0 using [Position.Relative]. - * Spawn confetti on random positions using [Position.between]. + * Spawn confetti on random positions using [Position.Between]. * @property delay the amount of milliseconds to wait before the rendering of the confetti starts * @property rotation enable the 3D rotation of a Confetti. See [Rotation] class for the configuration * options. Easily enable or disable it using [Rotation].enabled() or [Rotation].disabled() and @@ -52,7 +52,7 @@ data class Party( val position: Position = Position.Relative(0.5, 0.5), val delay: Int = 0, val rotation: Rotation = Rotation(), - val emitter: EmitterConfig + val emitter: EmitterConfig, ) /** @@ -90,7 +90,7 @@ sealed class Position { * @property y the y coordinate in pixels */ data class Absolute(val x: Float, val y: Float) : Position() { - fun between(value: Absolute): Position = between(this, value) + fun between(value: Absolute): Position = Between(this, value) } /** @@ -105,7 +105,7 @@ sealed class Position { * @property y the relative y coordinate as a double */ data class Relative(val x: Double, val y: Double) : Position() { - fun between(value: Relative): Position = between(this, value) + fun between(value: Relative): Position = Between(this, value) } /** @@ -114,7 +114,7 @@ sealed class Position { * Example: Relative(0.0, 0.0).between(Relative(1.0, 0.0)) * This will spawn confetti from the full width and top of the view */ - internal data class between(val min: Position, val max: Position) : Position() + internal data class Between(val min: Position, val max: Position) : Position() } /** @@ -132,10 +132,11 @@ data class Rotation( val speed: Float = 1f, val variance: Float = 0.5f, val multiplier2D: Float = 8f, - val multiplier3D: Float = 1.5f + val multiplier3D: Float = 1.5f, ) { companion object { fun enabled() = Rotation(enabled = true) + fun disabled() = Rotation(enabled = false) } } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartyFactory.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartyFactory.kt index 48f98a62..b4a19877 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartyFactory.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartyFactory.kt @@ -9,7 +9,6 @@ import nl.dionsegijn.konfetti.core.models.Size * See [Party] for documentation on the configuration settings */ class PartyFactory(val emitter: EmitterConfig) { - private var party: Party = Party(emitter = emitter) fun angle(angle: Int): PartyFactory { @@ -27,7 +26,10 @@ class PartyFactory(val emitter: EmitterConfig) { return this } - fun setSpeedBetween(minSpeed: Float, maxSpeed: Float): PartyFactory { + fun setSpeedBetween( + minSpeed: Float, + maxSpeed: Float, + ): PartyFactory { party = party.copy(speed = minSpeed, maxSpeed = maxSpeed) return this } @@ -42,28 +44,47 @@ class PartyFactory(val emitter: EmitterConfig) { return this } - fun position(x: Float, y: Float): PartyFactory { + fun position( + x: Float, + y: Float, + ): PartyFactory { party = party.copy(position = Position.Absolute(x, y)) return this } - fun position(minX: Float, minY: Float, maxX: Float, maxY: Float): PartyFactory { - party = party.copy( - position = Position.Absolute(minX, minY) - .between(Position.Absolute(maxX, maxY)) - ) + fun position( + minX: Float, + minY: Float, + maxX: Float, + maxY: Float, + ): PartyFactory { + party = + party.copy( + position = + Position.Absolute(minX, minY) + .between(Position.Absolute(maxX, maxY)), + ) return this } - fun position(x: Double, y: Double): PartyFactory { + fun position( + x: Double, + y: Double, + ): PartyFactory { party = party.copy(position = Position.Relative(x, y)) return this } - fun position(minX: Double, minY: Double, maxX: Double, maxY: Double): PartyFactory { - party = party.copy( - position = Position.Relative(minX, minY).between(Position.Relative(maxX, maxY)) - ) + fun position( + minX: Double, + minY: Double, + maxX: Double, + maxY: Double, + ): PartyFactory { + party = + party.copy( + position = Position.Relative(minX, minY).between(Position.Relative(maxX, maxY)), + ) return this } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartySystem.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartySystem.kt index 03b871ae..7806a538 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartySystem.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/PartySystem.kt @@ -15,9 +15,8 @@ import nl.dionsegijn.konfetti.core.models.CoreRect class PartySystem( val party: Party, val createdAt: Long = System.currentTimeMillis(), - pixelDensity: Float + pixelDensity: Float, ) { - var enabled = true private var emitter: BaseEmitter = PartyEmitter(party.emitter, pixelDensity) @@ -26,7 +25,10 @@ class PartySystem( // Called every frame to create and update the particles state // returns a list of particles that are ready to be rendered - fun render(deltaTime: Float, drawArea: CoreRect): List { + fun render( + deltaTime: Float, + drawArea: CoreRect, + ): List { if (enabled) { activeParticles.addAll(emitter.createConfetti(deltaTime, party, drawArea)) } @@ -43,8 +45,7 @@ class PartySystem( * @return true if the emitter is done emitting or false when it's still busy or needs to start * based on the delay */ - fun isDoneEmitting(): Boolean = - (emitter.isFinished() && activeParticles.size == 0) || (!enabled && activeParticles.size == 0) + fun isDoneEmitting(): Boolean = (emitter.isFinished() && activeParticles.size == 0) || (!enabled && activeParticles.size == 0) fun getActiveParticleAmount() = activeParticles.size } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/BaseEmitter.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/BaseEmitter.kt index 7171d712..4bea54cc 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/BaseEmitter.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/BaseEmitter.kt @@ -8,7 +8,6 @@ import nl.dionsegijn.konfetti.core.models.CoreRect * The emitter decides if a particle should be created and when the emitter is finished */ abstract class BaseEmitter { - /** * This function is called on each update when the [RenderSystem] is active * Keep this function as light as possible otherwise you'll slow down the render system diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/Confetti.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/Confetti.kt index 48386c28..4d28cd7e 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/Confetti.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/Confetti.kt @@ -26,7 +26,7 @@ import kotlin.math.abs class Confetti( var location: Vector, private val color: Int, - val width: Float, // sizeInPx + val width: Float, private val mass: Float, val shape: Shape, var lifespan: Long = -1L, @@ -36,9 +36,8 @@ class Confetti( var damping: Float, val rotationSpeed3D: Float = 1f, val rotationSpeed2D: Float = 1f, - val pixelDensity: Float + val pixelDensity: Float, ) { - companion object { private const val DEFAULT_FRAME_RATE = 60f private const val GRAVITY = 0.02f @@ -89,7 +88,10 @@ class Confetti( /** * Updates the state of the particle for each frame of the animation. */ - fun render(deltaTime: Float, drawArea: CoreRect) { + fun render( + deltaTime: Float, + drawArea: CoreRect, + ) { applyForce(gravity) update(deltaTime, drawArea) } @@ -98,7 +100,10 @@ class Confetti( * Updates the state of the particle based on its current acceleration, velocity, and location. * Also handles the fading out of the particle when its lifespan is over. */ - private fun update(deltaTime: Float, drawArea: CoreRect) { + private fun update( + deltaTime: Float, + drawArea: CoreRect, + ) { // Calculate frameRate dynamically, fallback to 60fps in case deltaTime is 0 frameRate = if (deltaTime > 0) 1f / deltaTime else DEFAULT_FRAME_RATE @@ -131,11 +136,12 @@ class Confetti( } private fun updateAlpha(deltaTime: Float) { - alpha = if (fadeOut) { - val interval = ALPHA_DECREMENT * deltaTime * frameRate - (alpha - interval.toInt()).coerceAtLeast(0) - } else { - 0 - } + alpha = + if (fadeOut) { + val interval = ALPHA_DECREMENT * deltaTime * frameRate + (alpha - interval.toInt()).coerceAtLeast(0) + } else { + 0 + } } } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/EmitterConfig.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/EmitterConfig.kt index b225b4fe..ad2d5ab1 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/EmitterConfig.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/EmitterConfig.kt @@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit */ data class Emitter( val duration: Long, - val timeUnit: TimeUnit = TimeUnit.MILLISECONDS + val timeUnit: TimeUnit = TimeUnit.MILLISECONDS, ) { /** * Max amount of particles that will be created over the duration that is set @@ -25,9 +25,8 @@ data class Emitter( * will be created over certain time */ class EmitterConfig( - emitter: Emitter + emitter: Emitter, ) { - /** Max time allowed to emit in milliseconds */ var emittingTime: Long = 0 diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitter.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitter.kt index df3c23f3..0fae8c51 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitter.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitter.kt @@ -20,10 +20,9 @@ import kotlin.math.sin class PartyEmitter( private val emitterConfig: EmitterConfig, private val pixelDensity: Float, - private val random: Random = Random() + private val random: Random = Random(), ) : BaseEmitter() { - - /* Keeping count of how many particles are created whilst running the emitter */ + // Keeping count of how many particles are created whilst running the emitter private var particlesCreated = 0 /** Elapsed time in milliseconds */ @@ -36,7 +35,11 @@ class PartyEmitter( * If timer isn't started yet, set initial start time * Create the first confetti immediately and update the last emitting time */ - override fun createConfetti(deltaTime: Float, party: Party, drawArea: CoreRect): List { + override fun createConfetti( + deltaTime: Float, + party: Party, + drawArea: CoreRect, + ): List { createParticleMs += deltaTime // Initial deltaTime can't be higher than the emittingTime, if so calculate @@ -68,7 +71,10 @@ class PartyEmitter( * @param party Configurations used for creating the initial Confetti states * @param drawArea the area and size of the canvas */ - private fun createParticle(party: Party, drawArea: CoreRect): Confetti { + private fun createParticle( + party: Party, + drawArea: CoreRect, + ): Confetti { particlesCreated++ with(party) { val randomSize = size[random.nextInt(size.size)] @@ -84,7 +90,7 @@ class PartyEmitter( damping = party.damping, rotationSpeed2D = rotation.rotationSpeed() * party.rotation.multiplier2D, rotationSpeed3D = rotation.rotationSpeed() * party.rotation.multiplier3D, - pixelDensity = pixelDensity + pixelDensity = pixelDensity, ) } } @@ -100,8 +106,11 @@ class PartyEmitter( } private fun Party.getSpeed(): Float = - if (maxSpeed == -1f) speed - else ((maxSpeed - speed) * random.nextFloat()) + speed + if (maxSpeed == -1f) { + speed + } else { + ((maxSpeed - speed) * random.nextFloat()) + speed + } /** * Get the mass with a slight variance added to create randomness between how each particle @@ -135,15 +144,15 @@ class PartyEmitter( is Position.Relative -> { Position.Absolute( drawArea.width * x.toFloat(), - drawArea.height * y.toFloat() + drawArea.height * y.toFloat(), ) } - is Position.between -> { + is Position.Between -> { val minPos = min.get(drawArea) val maxPos = max.get(drawArea) return Position.Absolute( x = random.nextFloat().times(maxPos.x.minus(minPos.x)) + minPos.x, - y = random.nextFloat().times(maxPos.y.minus(minPos.y)) + minPos.y + y = random.nextFloat().times(maxPos.y.minus(minPos.y)) + minPos.y, ) } } @@ -170,6 +179,8 @@ class PartyEmitter( override fun isFinished(): Boolean { return if (emitterConfig.emittingTime > 0L) { elapsedTime >= emitterConfig.emittingTime - } else false + } else { + false + } } } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImage.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImage.kt index bb04960a..0eb859bd 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImage.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImage.kt @@ -8,5 +8,5 @@ interface CoreImage { data class ReferenceImage( val reference: Int, override val width: Int, - override val height: Int + override val height: Int, ) : CoreImage diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImageStore.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImageStore.kt index c48c838c..802c8cd0 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImageStore.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreImageStore.kt @@ -2,5 +2,6 @@ package nl.dionsegijn.konfetti.core.models interface CoreImageStore { fun storeImage(image: T): Int + fun getImage(id: Int): T? } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreRect.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreRect.kt index 62e29549..5a848bf4 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreRect.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/CoreRect.kt @@ -6,14 +6,22 @@ interface CoreRect { var width: Float var height: Float - fun set(x: Float, y: Float, width: Float, height: Float) { + fun set( + x: Float, + y: Float, + width: Float, + height: Float, + ) { this.x = x this.y = y this.width = width this.height = height } - fun contains(px: Int, py: Int): Boolean { + fun contains( + px: Int, + py: Int, + ): Boolean { return px >= x && px <= x + width && py >= y && py <= y + height } } @@ -22,13 +30,21 @@ class CoreRectImpl( override var x: Float = 0f, override var y: Float = 0f, override var width: Float = 0f, - override var height: Float = 0f + override var height: Float = 0f, ) : CoreRect { - override fun set(x: Float, y: Float, width: Float, height: Float) { + override fun set( + x: Float, + y: Float, + width: Float, + height: Float, + ) { super.set(x, y, width, height) } - override fun contains(px: Int, py: Int): Boolean { + override fun contains( + px: Int, + py: Int, + ): Boolean { return super.contains(px, py) } } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Shape.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Shape.kt index 4af866c6..b720754f 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Shape.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Shape.kt @@ -5,10 +5,12 @@ sealed interface Shape { // Default replacement for RectF val rect = CoreRectImpl() } + object Square : Shape + class Rectangle( /** The ratio of height to width. Must be within range [0, 1] */ - val heightRatio: Float + val heightRatio: Float, ) : Shape { init { require(heightRatio in 0f..1f) @@ -26,7 +28,6 @@ sealed interface Shape { val tint: Boolean = true, val applyAlpha: Boolean = true, ) : Shape { - val heightRatio = if (image.height == -1 && image.width == -1) { // If the image has no intrinsic size, fill the available space. diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Size.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Size.kt index f1c50238..3c521afa 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Size.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Size.kt @@ -9,7 +9,6 @@ package nl.dionsegijn.konfetti.core.models * each particle is. Default is 0.2f for a slight difference in mass for each particle. */ data class Size(val sizeInDp: Int, val mass: Float = 5f, val massVariance: Float = 0.2f) { - init { require(mass != 0F) { "mass=$mass must be != 0" } } diff --git a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Vector.kt b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Vector.kt index 0ddd4fa0..dbb26fce 100644 --- a/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Vector.kt +++ b/konfetti/core/src/main/java/nl/dionsegijn/konfetti/core/models/Vector.kt @@ -6,7 +6,10 @@ data class Vector(var x: Float = 0f, var y: Float = 0f) { y += v.y } - fun addScaled(v: Vector, s: Float) { + fun addScaled( + v: Vector, + s: Float, + ) { x += v.x * s y += v.y * s } diff --git a/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/PartySystemTest.kt b/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/PartySystemTest.kt index 82305be9..ab41099d 100644 --- a/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/PartySystemTest.kt +++ b/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/PartySystemTest.kt @@ -9,20 +9,21 @@ import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito class PartySystemTest { - - private val rect: CoreRect = Mockito.mock(CoreRectImpl::class.java).apply { - Mockito.`when`(height).thenReturn(1000f) - Mockito.`when`(contains(anyInt(), anyInt())).thenReturn(true) - } + private val rect: CoreRect = + Mockito.mock(CoreRectImpl::class.java).apply { + Mockito.`when`(height).thenReturn(1000f) + Mockito.`when`(contains(anyInt(), anyInt())).thenReturn(true) + } // Average between for each frame private val deltaTime = 0.017f @Test fun `Test creating particle every 25ms`() { - val party = Party( - emitter = Emitter(100L).max(4) - ) + val party = + Party( + emitter = Emitter(100L).max(4), + ) val system = PartySystem(party, pixelDensity = 1f) Assert.assertTrue(system.enabled) @@ -40,9 +41,10 @@ class PartySystemTest { @Test fun `Test PartySystem set to disabled stops generating particles`() { - val party = Party( - emitter = Emitter(100L).max(4) - ) + val party = + Party( + emitter = Emitter(100L).max(4), + ) val system = PartySystem(party, pixelDensity = 1f) Assert.assertTrue(system.enabled) @@ -65,11 +67,12 @@ class PartySystemTest { @Test fun `Test PartySystem is done Emitting`() { - val party = Party( - timeToLive = 1L, - fadeOutEnabled = false, - emitter = Emitter(100).max(2) - ) + val party = + Party( + timeToLive = 1L, + fadeOutEnabled = false, + emitter = Emitter(100).max(2), + ) val system = PartySystem(party, pixelDensity = 1f) // Set drawArea to 1 pixel to let every particle directly disappear for this test @@ -93,11 +96,14 @@ class PartySystemTest { @Test fun `Test PartySystem remove dead particles`() { - val party = Party( - timeToLive = 18L, // removes particles after two frames - fadeOutEnabled = false, - emitter = Emitter(100L).max(5) // Create particle every 20ms - ) + // removes particles after two frames + // Create particle every 20ms + val party = + Party( + timeToLive = 18L, + fadeOutEnabled = false, + emitter = Emitter(100L).max(5), + ) val system = PartySystem(party, pixelDensity = 1f) // Every 20ms a new particle is created and every two frames they're removed diff --git a/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitterTest.kt b/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitterTest.kt index ce1f7b1b..70b8abb8 100644 --- a/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitterTest.kt +++ b/konfetti/core/src/test/java/nl/dionsegijn/konfetti/core/emitter/PartyEmitterTest.kt @@ -28,28 +28,32 @@ class PartyEmitterTest { private val deltaTime = 0.017f // Test Party object - private val party = Party( - angle = Angle.TOP, - spread = 0, - speed = 30f, - maxSpeed = -1f, - damping = 0.9f, - size = listOf(Size(sizeInDp = 6, mass = 5f, massVariance = 0f)), - colors = listOf(0xFF0000), - shapes = listOf(Shape.Square), - timeToLive = 1000L, - fadeOutEnabled = false, - position = Position.Absolute(100f, 100f), - delay = 0, - rotation = Rotation(), - emitter = Emitter(100L).max(10) // Create confetti every 10ms - ) + // Create confetti every 10ms + private val party = + Party( + angle = Angle.TOP, + spread = 0, + speed = 30f, + maxSpeed = -1f, + damping = 0.9f, + size = listOf(Size(sizeInDp = 6, mass = 5f, massVariance = 0f)), + colors = listOf(0xFF0000), + shapes = listOf(Shape.Square), + timeToLive = 1000L, + fadeOutEnabled = false, + position = Position.Absolute(100f, 100f), + delay = 0, + rotation = Rotation(), + emitter = Emitter(100L).max(10), + ) @Test fun `Create confetti every 25ms and then finish`() { - val party = Party( - emitter = Emitter(100L).max(4) // Create confetti every 25ms - ) + // Create confetti every 25ms + val party = + Party( + emitter = Emitter(100L).max(4), + ) val emitter = PartyEmitter(party.emitter, 1f) val r1 = emitter.createConfetti(deltaTime, party, drawArea) // 0.017f @@ -93,11 +97,12 @@ class PartyEmitterTest { fun `Initial state confetti with rotation disabled`() { val emitter = PartyEmitter(party.emitter, 1f) - val r1 = emitter.createConfetti( - deltaTime, - party.copy(rotation = Rotation.disabled()), - drawArea - ) // 0.017f + val r1 = + emitter.createConfetti( + deltaTime, + party.copy(rotation = Rotation.disabled()), + drawArea, + ) // 0.017f with(r1.first()) { Assert.assertEquals(0.0f, rotationSpeed2D) @@ -109,11 +114,12 @@ class PartyEmitterTest { fun `Initial state confetti with relative position`() { val emitter = PartyEmitter(party.emitter, 1f) - val r1 = emitter.createConfetti( - deltaTime, - party.copy(position = Position.Relative(0.5, 0.5)), - drawArea - ) // 0.017f + val r1 = + emitter.createConfetti( + deltaTime, + party.copy(position = Position.Relative(0.5, 0.5)), + drawArea, + ) // 0.017f with(r1.first()) { Assert.assertEquals(Vector(500f, 500f), location) diff --git a/konfetti/xml/build.gradle.kts b/konfetti/xml/build.gradle.kts index cfc5a9e5..cd965e66 100644 --- a/konfetti/xml/build.gradle.kts +++ b/konfetti/xml/build.gradle.kts @@ -9,12 +9,12 @@ apply(from = "../../scripts/publish-module.gradle.kts") spotless { kotlin { - ktlint("0.37.2") + ktlint("1.1.0") target("src/**/*.kt") } java { removeUnusedImports() - googleJavaFormat("1.5") + googleJavaFormat("1.15.0") target("**/*.java") } } diff --git a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/DrawShapes.kt b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/DrawShapes.kt index d50fd024..e279d2b3 100644 --- a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/DrawShapes.kt +++ b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/DrawShapes.kt @@ -21,8 +21,12 @@ import nl.dionsegijn.konfetti.xml.image.ImageStore * `size` and must vertically/horizontally center their asset if it does not have an equal width * and height. */ -fun Shape.draw(canvas: Canvas, paint: Paint, size: Float, imageStore: ImageStore) { - +fun Shape.draw( + canvas: Canvas, + paint: Paint, + size: Float, + imageStore: ImageStore, +) { when (this) { Square -> canvas.drawRect(0f, 0f, size, size, paint) Circle -> { diff --git a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/KonfettiView.kt b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/KonfettiView.kt index 90ed4053..fa756df5 100644 --- a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/KonfettiView.kt +++ b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/KonfettiView.kt @@ -23,7 +23,6 @@ import nl.dionsegijn.konfetti.xml.listeners.OnParticleSystemUpdateListener * pass the canvas to each system where each system will handle the rendering. */ open class KonfettiView : View { - constructor(context: Context?) : super(context) constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) @@ -106,7 +105,7 @@ open class KonfettiView : View { party.map { onParticleSystemUpdateListener?.onParticleSystemStarted(this, it, systems.size) PartySystem(party = storeImages(it), pixelDensity = Resources.getSystem().displayMetrics.density) - } + }, ) invalidate() } @@ -117,7 +116,7 @@ open class KonfettiView : View { storeImages(it) onParticleSystemUpdateListener?.onParticleSystemStarted(this, it, systems.size) PartySystem(party = storeImages(it), pixelDensity = Resources.getSystem().displayMetrics.density) - } + }, ) invalidate() } @@ -136,15 +135,16 @@ open class KonfettiView : View { * @return A new Party object with the transformed shapes. */ private fun storeImages(party: Party): Party { - val transformedShapes = party.shapes.map { shape -> - when (shape) { - is Shape.DrawableShape -> { - val referenceImage = drawableToReferenceImage(shape.image as DrawableImage) - shape.copy(image = referenceImage) + val transformedShapes = + party.shapes.map { shape -> + when (shape) { + is Shape.DrawableShape -> { + val referenceImage = drawableToReferenceImage(shape.image as DrawableImage) + shape.copy(image = referenceImage) + } + else -> shape } - else -> shape } - } return party.copy(shapes = transformedShapes) } @@ -211,12 +211,20 @@ open class KonfettiView : View { } } - override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + override fun onSizeChanged( + w: Int, + h: Int, + oldw: Int, + oldh: Int, + ) { super.onSizeChanged(w, h, oldw, oldh) drawArea = CoreRectImpl(0f, 0f, w.toFloat(), h.toFloat()) } - override fun onVisibilityChanged(changedView: View, visibility: Int) { + override fun onVisibilityChanged( + changedView: View, + visibility: Int, + ) { super.onVisibilityChanged(changedView, visibility) timer.reset() } diff --git a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/DrawableImage.kt b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/DrawableImage.kt index 1e38a9fc..efcf36ce 100644 --- a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/DrawableImage.kt +++ b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/DrawableImage.kt @@ -6,5 +6,5 @@ import nl.dionsegijn.konfetti.core.models.CoreImage data class DrawableImage( val drawable: Drawable, override val width: Int, - override val height: Int + override val height: Int, ) : CoreImage diff --git a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/ImageUtil.kt b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/ImageUtil.kt index f49300d0..31c2b7ff 100644 --- a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/ImageUtil.kt +++ b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/image/ImageUtil.kt @@ -4,12 +4,11 @@ import android.graphics.drawable.Drawable import nl.dionsegijn.konfetti.core.models.Shape object ImageUtil { - @JvmStatic fun loadDrawable( drawable: Drawable, tint: Boolean = true, - applyAlpha: Boolean = true + applyAlpha: Boolean = true, ): Shape.DrawableShape { val width = drawable.intrinsicWidth val height = drawable.intrinsicHeight diff --git a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/listeners/OnParticleSystemUpdateListener.kt b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/listeners/OnParticleSystemUpdateListener.kt index 887738e1..c328b93a 100644 --- a/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/listeners/OnParticleSystemUpdateListener.kt +++ b/konfetti/xml/src/main/java/nl/dionsegijn/konfetti/xml/listeners/OnParticleSystemUpdateListener.kt @@ -7,6 +7,15 @@ import nl.dionsegijn.konfetti.xml.KonfettiView * Created by dionsegijn on 5/31/17. */ interface OnParticleSystemUpdateListener { - fun onParticleSystemStarted(view: KonfettiView, party: Party, activeSystems: Int) - fun onParticleSystemEnded(view: KonfettiView, party: Party, activeSystems: Int) + fun onParticleSystemStarted( + view: KonfettiView, + party: Party, + activeSystems: Int, + ) + + fun onParticleSystemEnded( + view: KonfettiView, + party: Party, + activeSystems: Int, + ) } diff --git a/samples/compose-kotlin/build.gradle.kts b/samples/compose-kotlin/build.gradle.kts index 1e600356..554aeee8 100644 --- a/samples/compose-kotlin/build.gradle.kts +++ b/samples/compose-kotlin/build.gradle.kts @@ -6,12 +6,12 @@ plugins { spotless { kotlin { - ktlint("0.37.2") + ktlint("1.1.0") target("src/**/*.kt") } java { removeUnusedImports() - googleJavaFormat("1.5") + googleJavaFormat("1.15.0") target("**/*.java") } } diff --git a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ComposeActivity.kt b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ComposeActivity.kt index efe1adfb..4701d94a 100644 --- a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ComposeActivity.kt +++ b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ComposeActivity.kt @@ -27,7 +27,6 @@ import nl.dionsegijn.konfetti.xml.image.ImageUtil import nl.dionsegijn.xml.compose.ui.theme.KonfettiTheme class ComposeActivity : ComponentActivity() { - private val viewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { @@ -46,19 +45,19 @@ class ComposeActivity : ComponentActivity() { @Composable fun KonfettiUI(viewModel: KonfettiViewModel = KonfettiViewModel()) { - val state: KonfettiViewModel.State by viewModel.state.observeAsState( - KonfettiViewModel.State.Idle + KonfettiViewModel.State.Idle, ) val drawable = AppCompatResources.getDrawable(LocalContext.current, R.drawable.ic_heart) when (val newState = state) { KonfettiViewModel.State.Idle -> { Column( - modifier = Modifier - .fillMaxWidth() - .fillMaxHeight(), + modifier = + Modifier + .fillMaxWidth() + .fillMaxHeight(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Button(onClick = { viewModel.festive(ImageUtil.loadDrawable(drawable!!)) }) { Text( @@ -82,14 +81,19 @@ fun KonfettiUI(viewModel: KonfettiViewModel = KonfettiViewModel()) { } } } - is KonfettiViewModel.State.Started -> KonfettiView( - modifier = Modifier.fillMaxSize(), - parties = newState.party, - updateListener = object : OnParticleSystemUpdateListener { - override fun onParticleSystemEnded(system: PartySystem, activeSystems: Int) { - if (activeSystems == 0) viewModel.ended() - } - } - ) + is KonfettiViewModel.State.Started -> + KonfettiView( + modifier = Modifier.fillMaxSize(), + parties = newState.party, + updateListener = + object : OnParticleSystemUpdateListener { + override fun onParticleSystemEnded( + system: PartySystem, + activeSystems: Int, + ) { + if (activeSystems == 0) viewModel.ended() + } + }, + ) } } diff --git a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/KonfettiViewModel.kt b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/KonfettiViewModel.kt index 78f97978..e65505e4 100644 --- a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/KonfettiViewModel.kt +++ b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/KonfettiViewModel.kt @@ -8,7 +8,6 @@ import nl.dionsegijn.konfetti.core.models.Shape import nl.dionsegijn.samples.shared.Presets class KonfettiViewModel : ViewModel() { - private val _state = MutableLiveData(State.Idle) val state: LiveData = _state @@ -46,6 +45,7 @@ class KonfettiViewModel : ViewModel() { sealed class State { class Started(val party: List) : State() + object Idle : State() } } diff --git a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Shape.kt b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Shape.kt index da00a844..1f15493d 100644 --- a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Shape.kt +++ b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Shape.kt @@ -4,8 +4,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes import androidx.compose.ui.unit.dp -val Shapes = Shapes( - small = RoundedCornerShape(4.dp), - medium = RoundedCornerShape(4.dp), - large = RoundedCornerShape(0.dp) -) +val Shapes = + Shapes( + small = RoundedCornerShape(4.dp), + medium = RoundedCornerShape(4.dp), + large = RoundedCornerShape(0.dp), + ) diff --git a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Theme.kt b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Theme.kt index 6e0cb36c..8b7f3632 100644 --- a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Theme.kt +++ b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Theme.kt @@ -6,17 +6,18 @@ import androidx.compose.material.darkColors import androidx.compose.material.lightColors import androidx.compose.runtime.Composable -private val DarkColorPalette = darkColors( - primary = Purple200, - primaryVariant = Purple700, - secondary = Teal200 -) - -private val LightColorPalette = lightColors( - primary = Purple500, - primaryVariant = Purple700, - secondary = Teal200 +private val DarkColorPalette = + darkColors( + primary = Purple200, + primaryVariant = Purple700, + secondary = Teal200, + ) +private val LightColorPalette = + lightColors( + primary = Purple500, + primaryVariant = Purple700, + secondary = Teal200, /* Other default colors to override background = Color.White, surface = Color.White, @@ -24,21 +25,27 @@ private val LightColorPalette = lightColors( onSecondary = Color.Black, onBackground = Color.Black, onSurface = Color.Black, - */ -) + */ + ) @Composable -fun KonfettiTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { - val colors = if (darkTheme) { - DarkColorPalette - } else { - LightColorPalette - } +fun KonfettiTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + content: + @Composable() + () -> Unit, +) { + val colors = + if (darkTheme) { + DarkColorPalette + } else { + LightColorPalette + } MaterialTheme( colors = colors, typography = Typography, shapes = Shapes, - content = content + content = content, ) } diff --git a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Type.kt b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Type.kt index 232b1fed..4ff36a63 100644 --- a/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Type.kt +++ b/samples/compose-kotlin/src/main/java/nl/dionsegijn/xml/compose/ui/theme/Type.kt @@ -7,12 +7,14 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp // Set of Material typography styles to start with -val Typography = Typography( - body1 = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp - ) +val Typography = + Typography( + body1 = + TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + ), /* Other default text styles to override button = TextStyle( fontFamily = FontFamily.Default, @@ -24,5 +26,5 @@ val Typography = Typography( fontWeight = FontWeight.Normal, fontSize = 12.sp ) - */ -) + */ + ) diff --git a/samples/xml-java/build.gradle.kts b/samples/xml-java/build.gradle.kts index 1872df26..9f5b94c9 100644 --- a/samples/xml-java/build.gradle.kts +++ b/samples/xml-java/build.gradle.kts @@ -5,12 +5,12 @@ plugins { spotless { kotlin { - ktlint("0.37.2") + ktlint("1.1.0") target("src/**/*.kt") } java { removeUnusedImports() - googleJavaFormat("1.5") + googleJavaFormat("1.15.0") target("**/*.java") } } diff --git a/samples/xml-java/src/androidTest/java/nl/dionsegijn/xml/java/MainActivityTest.java b/samples/xml-java/src/androidTest/java/nl/dionsegijn/xml/java/MainActivityTest.java index 54e6379f..8635169b 100644 --- a/samples/xml-java/src/androidTest/java/nl/dionsegijn/xml/java/MainActivityTest.java +++ b/samples/xml-java/src/androidTest/java/nl/dionsegijn/xml/java/MainActivityTest.java @@ -1,6 +1,5 @@ package nl.dionsegijn.xml.java; - import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; @@ -11,12 +10,10 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; - import androidx.test.espresso.ViewInteraction; import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; - import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; @@ -28,59 +25,57 @@ @RunWith(AndroidJUnit4.class) public class MainActivityTest { - @Rule - public ActivityScenarioRule mActivityScenarioRule = - new ActivityScenarioRule<>(MainActivity.class); + @Rule + public ActivityScenarioRule mActivityScenarioRule = + new ActivityScenarioRule<>(MainActivity.class); - @Test - public void mainActivityTest() { - ViewInteraction materialButton = onView( - allOf(withId(R.id.btnExplode), withText("Explode"), - childAtPosition( - childAtPosition( - withId(android.R.id.content), - 0), - 1), - isDisplayed())); - materialButton.perform(click()); + @Test + public void mainActivityTest() { + ViewInteraction materialButton = + onView( + allOf( + withId(R.id.btnExplode), + withText("Explode"), + childAtPosition(childAtPosition(withId(android.R.id.content), 0), 1), + isDisplayed())); + materialButton.perform(click()); - ViewInteraction materialButton2 = onView( - allOf(withId(R.id.btnParade), withText("Parade"), - childAtPosition( - childAtPosition( - withId(android.R.id.content), - 0), - 2), - isDisplayed())); - materialButton2.perform(click()); + ViewInteraction materialButton2 = + onView( + allOf( + withId(R.id.btnParade), + withText("Parade"), + childAtPosition(childAtPosition(withId(android.R.id.content), 0), 2), + isDisplayed())); + materialButton2.perform(click()); - ViewInteraction materialButton3 = onView( - allOf(withId(R.id.btnRain), withText("Rain"), - childAtPosition( - childAtPosition( - withId(android.R.id.content), - 0), - 3), - isDisplayed())); - materialButton3.perform(click()); - } + ViewInteraction materialButton3 = + onView( + allOf( + withId(R.id.btnRain), + withText("Rain"), + childAtPosition(childAtPosition(withId(android.R.id.content), 0), 3), + isDisplayed())); + materialButton3.perform(click()); + } - private static Matcher childAtPosition( - final Matcher parentMatcher, final int position) { + private static Matcher childAtPosition( + final Matcher parentMatcher, final int position) { - return new TypeSafeMatcher() { - @Override - public void describeTo(Description description) { - description.appendText("Child at position " + position + " in parent "); - parentMatcher.describeTo(description); - } + return new TypeSafeMatcher() { + @Override + public void describeTo(Description description) { + description.appendText("Child at position " + position + " in parent "); + parentMatcher.describeTo(description); + } - @Override - public boolean matchesSafely(View view) { - ViewParent parent = view.getParent(); - return parent instanceof ViewGroup && parentMatcher.matches(parent) - && view.equals(((ViewGroup) parent).getChildAt(position)); - } - }; - } + @Override + public boolean matchesSafely(View view) { + ViewParent parent = view.getParent(); + return parent instanceof ViewGroup + && parentMatcher.matches(parent) + && view.equals(((ViewGroup) parent).getChildAt(position)); + } + }; + } } diff --git a/samples/xml-java/src/main/java/nl/dionsegijn/xml/java/MainActivity.java b/samples/xml-java/src/main/java/nl/dionsegijn/xml/java/MainActivity.java index 13970212..cac75ec1 100644 --- a/samples/xml-java/src/main/java/nl/dionsegijn/xml/java/MainActivity.java +++ b/samples/xml-java/src/main/java/nl/dionsegijn/xml/java/MainActivity.java @@ -4,13 +4,10 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; - import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; - import java.util.Arrays; import java.util.concurrent.TimeUnit; - import nl.dionsegijn.konfetti.core.Angle; import nl.dionsegijn.konfetti.core.Party; import nl.dionsegijn.konfetti.core.PartyFactory; @@ -19,94 +16,97 @@ import nl.dionsegijn.konfetti.core.emitter.EmitterConfig; import nl.dionsegijn.konfetti.core.models.Shape; import nl.dionsegijn.konfetti.core.models.Size; -import nl.dionsegijn.konfetti.xml.image.ImageUtil; import nl.dionsegijn.konfetti.xml.KonfettiView; +import nl.dionsegijn.konfetti.xml.image.ImageUtil; public class MainActivity extends AppCompatActivity { - private KonfettiView konfettiView = null; - private Shape.DrawableShape drawableShape = null; + private KonfettiView konfettiView = null; + private Shape.DrawableShape drawableShape = null; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); - final Drawable drawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_heart); - drawableShape = ImageUtil.loadDrawable(drawable, true, true); + final Drawable drawable = + ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_heart); + drawableShape = ImageUtil.loadDrawable(drawable, true, true); - konfettiView = findViewById(R.id.konfettiView); - EmitterConfig emitterConfig = new Emitter(5L, TimeUnit.SECONDS).perSecond(50); - Party party = new PartyFactory(emitterConfig) - .angle(270) - .spread(90) - .setSpeedBetween(1f, 5f) - .timeToLive(2000L) - .shapes(new Shape.Rectangle(0.2f), drawableShape) - .sizes(new Size(12, 5f, 0.2f)) - .position(0.0, 0.0, 1.0, 0.0) - .build(); - konfettiView.setOnClickListener(view -> - konfettiView.start(party) - ); + konfettiView = findViewById(R.id.konfettiView); + EmitterConfig emitterConfig = new Emitter(5L, TimeUnit.SECONDS).perSecond(50); + Party party = + new PartyFactory(emitterConfig) + .angle(270) + .spread(90) + .setSpeedBetween(1f, 5f) + .timeToLive(2000L) + .shapes(new Shape.Rectangle(0.2f), drawableShape) + .sizes(new Size(12, 5f, 0.2f)) + .position(0.0, 0.0, 1.0, 0.0) + .build(); + konfettiView.setOnClickListener(view -> konfettiView.start(party)); - findViewById(R.id.btnExplode).setOnClickListener(v -> { - explode(); - }); - findViewById(R.id.btnParade).setOnClickListener(v -> { - parade(); - }); - findViewById(R.id.btnRain).setOnClickListener(v -> { - rain(); - }); - } + findViewById(R.id.btnExplode) + .setOnClickListener( + v -> { + explode(); + }); + findViewById(R.id.btnParade) + .setOnClickListener( + v -> { + parade(); + }); + findViewById(R.id.btnRain) + .setOnClickListener( + v -> { + rain(); + }); + } - public void explode() { - EmitterConfig emitterConfig = new Emitter(100L, TimeUnit.MILLISECONDS).max(100); - konfettiView.start( - new PartyFactory(emitterConfig) - .spread(360) - .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) - .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) - .setSpeedBetween(0f, 30f) - .position(new Relative(0.5, 0.3)) - .build() - ); - } + public void explode() { + EmitterConfig emitterConfig = new Emitter(100L, TimeUnit.MILLISECONDS).max(100); + konfettiView.start( + new PartyFactory(emitterConfig) + .spread(360) + .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) + .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) + .setSpeedBetween(0f, 30f) + .position(new Relative(0.5, 0.3)) + .build()); + } - public void parade() { - EmitterConfig emitterConfig = new Emitter(5, TimeUnit.SECONDS).perSecond(30); - konfettiView.start( - new PartyFactory(emitterConfig) - .angle(Angle.RIGHT - 45) - .spread(Spread.SMALL) - .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) - .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) - .setSpeedBetween(10f, 30f) - .position(new Relative(0.0, 0.5)) - .build(), - new PartyFactory(emitterConfig) - .angle(Angle.LEFT + 45) - .spread(Spread.SMALL) - .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) - .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) - .setSpeedBetween(10f, 30f) - .position(new Relative(1.0, 0.5)) - .build() - ); - } + public void parade() { + EmitterConfig emitterConfig = new Emitter(5, TimeUnit.SECONDS).perSecond(30); + konfettiView.start( + new PartyFactory(emitterConfig) + .angle(Angle.RIGHT - 45) + .spread(Spread.SMALL) + .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) + .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) + .setSpeedBetween(10f, 30f) + .position(new Relative(0.0, 0.5)) + .build(), + new PartyFactory(emitterConfig) + .angle(Angle.LEFT + 45) + .spread(Spread.SMALL) + .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) + .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) + .setSpeedBetween(10f, 30f) + .position(new Relative(1.0, 0.5)) + .build()); + } - public void rain() { - EmitterConfig emitterConfig = new Emitter(5, TimeUnit.SECONDS).perSecond(100); - konfettiView.start( - new PartyFactory(emitterConfig) - .angle(Angle.BOTTOM) - .spread(Spread.ROUND) - .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) - .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) - .setSpeedBetween(0f, 15f) - .position(new Relative(0.0, 0.0).between(new Relative(1.0, 0.0))) - .build() - ); - } + public void rain() { + EmitterConfig emitterConfig = new Emitter(5, TimeUnit.SECONDS).perSecond(100); + konfettiView.start( + new PartyFactory(emitterConfig) + .angle(Angle.BOTTOM) + .spread(Spread.ROUND) + .shapes(Arrays.asList(Shape.Square.INSTANCE, Shape.Circle.INSTANCE, drawableShape)) + .colors(Arrays.asList(0xfce18a, 0xff726d, 0xf4306d, 0xb48def)) + .setSpeedBetween(0f, 15f) + .position(new Relative(0.0, 0.0).between(new Relative(1.0, 0.0))) + .build()); + } } diff --git a/samples/xml-kotlin/build.gradle.kts b/samples/xml-kotlin/build.gradle.kts index 76ee2085..e29e0c9d 100644 --- a/samples/xml-kotlin/build.gradle.kts +++ b/samples/xml-kotlin/build.gradle.kts @@ -6,12 +6,12 @@ plugins { spotless { kotlin { - ktlint("0.37.2") + ktlint("1.1.0") target("src/**/*.kt") } java { removeUnusedImports() - googleJavaFormat("1.5") + googleJavaFormat("1.15.0") target("**/*.java") } } diff --git a/samples/xml-kotlin/src/androidTest/java/nl/dionsegijn/xml/kotlin/MainActivityTest.kt b/samples/xml-kotlin/src/androidTest/java/nl/dionsegijn/xml/kotlin/MainActivityTest.kt index 0e9eeef8..c4824dca 100644 --- a/samples/xml-kotlin/src/androidTest/java/nl/dionsegijn/xml/kotlin/MainActivityTest.kt +++ b/samples/xml-kotlin/src/androidTest/java/nl/dionsegijn/xml/kotlin/MainActivityTest.kt @@ -1,9 +1,10 @@ import android.view.View import android.view.ViewGroup import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.* -import androidx.test.espresso.assertion.ViewAssertions.* -import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest @@ -20,17 +21,17 @@ import org.junit.runner.RunWith @LargeTest @RunWith(AndroidJUnit4::class) class MainActivityTest { - @Rule @JvmField var mActivityScenarioRule = ActivityScenarioRule(MainActivity::class.java) - private val testButtons = listOf( - TestButton(R.id.btnFestive, "Festive"), - TestButton(R.id.btnExplode, "Explode"), - TestButton(R.id.btnParade, "Parade"), - TestButton(R.id.btnRain, "Rain"), - ) + private val testButtons = + listOf( + TestButton(R.id.btnFestive, "Festive"), + TestButton(R.id.btnExplode, "Explode"), + TestButton(R.id.btnParade, "Parade"), + TestButton(R.id.btnRain, "Rain"), + ) @Test fun mainActivityTest() { @@ -39,27 +40,33 @@ class MainActivityTest { } } - private fun runTestForButtonWithText(viewId: Int, buttonText: String, position: Int) { - val materialButton = onView( - allOf( - withId(viewId), withText(buttonText), - childAtPosition( + private fun runTestForButtonWithText( + viewId: Int, + buttonText: String, + position: Int, + ) { + val materialButton = + onView( + allOf( + withId(viewId), + withText(buttonText), childAtPosition( - withId(android.R.id.content), - 0 + childAtPosition( + withId(android.R.id.content), + 0, + ), + position, ), - position + isDisplayed(), ), - isDisplayed() ) - ) materialButton.perform(click()) } private fun childAtPosition( - parentMatcher: Matcher, position: Int + parentMatcher: Matcher, + position: Int, ): Matcher { - return object : TypeSafeMatcher() { override fun describeTo(description: Description) { description.appendText("Child at position $position in parent ") @@ -68,8 +75,8 @@ class MainActivityTest { public override fun matchesSafely(view: View): Boolean { val parent = view.parent - return parent is ViewGroup && parentMatcher.matches(parent) - && view == parent.getChildAt(position) + return parent is ViewGroup && parentMatcher.matches(parent) && + view == parent.getChildAt(position) } } } diff --git a/samples/xml-kotlin/src/main/java/nl/dionsegijn/xml/kotlin/MainActivity.kt b/samples/xml-kotlin/src/main/java/nl/dionsegijn/xml/kotlin/MainActivity.kt index d1426acf..2c5b1bb5 100644 --- a/samples/xml-kotlin/src/main/java/nl/dionsegijn/xml/kotlin/MainActivity.kt +++ b/samples/xml-kotlin/src/main/java/nl/dionsegijn/xml/kotlin/MainActivity.kt @@ -9,7 +9,6 @@ import nl.dionsegijn.konfetti.xml.image.ImageUtil import nl.dionsegijn.samples.shared.Presets class MainActivity : AppCompatActivity() { - private lateinit var viewKonfetti: KonfettiView override fun onCreate(savedInstanceState: Bundle?) {