
org.pushingpixels.torch.KTimeline.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of radiance-torch Show documentation
Show all versions of radiance-torch Show documentation
Building modern, elegant and fast Swing applications
The newest version!
/*
* Copyright (c) 2005-2021 Radiance Kirill Grouchnikov. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.pushingpixels.torch
import org.pushingpixels.trident.api.Timeline
import org.pushingpixels.trident.api.callback.TimelineCallback
import org.pushingpixels.trident.api.callback.TimelineCallbackAdapter
import org.pushingpixels.trident.api.ease.TimelineEase
import org.pushingpixels.trident.api.interpolator.KeyFrames
import org.pushingpixels.trident.api.swing.SwingComponentTimeline
import org.pushingpixels.trident.api.swing.SwingRepaintCallback
import org.pushingpixels.trident.api.swing.SwingRepaintTimeline
import java.awt.Component
import java.awt.Rectangle
import java.awt.Window
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KProperty
// Annotation to control the receiver scoping in the Torch DSL
@DslMarker
internal annotation class TorchElementMarker
@TorchElementMarker
public open class KTimeline {
public var secondaryId: Comparable<*>? = null
public var duration: Long = Timeline.DEFAULT_DURATION
public var initialDelay: Long = 0
public var cycleDelay: Long = 0
public var repeatCount: Int = 0
public var repeatBehavior: Timeline.RepeatBehavior? = null
private val callbacks: MutableList = ArrayList()
public var name: String? = null
internal val properties: MutableList> = ArrayList()
private val propertiesGoingThrough: MutableList> = ArrayList()
public var ease: TimelineEase = Timeline.DEFAULT_EASE
private var onTimelineStateChangedList: MutableList<(Timeline.TimelineState, Timeline.TimelineState,
Float, Float) -> Unit> = ArrayList()
private var onTimelinePulseList: MutableList<(Float, Float) -> Unit> = ArrayList()
public fun property(fromTo: PropertyFromTo<*>) {
properties.add(fromTo)
}
public fun property(goingThrough: PropertyGoingThrough<*>) {
propertiesGoingThrough.add(goingThrough)
}
public fun callback(callback: TimelineCallback) {
callbacks.add(callback)
}
public fun onTimelineStateChanged(callback: (Timeline.TimelineState, Timeline.TimelineState,
Float, Float) -> Unit) {
onTimelineStateChangedList.add(callback)
}
public fun onTimelineDone(callback: () -> Unit) {
onTimelineStateChangedList.add { _, newState, _, _ ->
if (newState == Timeline.TimelineState.DONE) {
callback.invoke()
}
}
}
public fun onTimelinePulse(callback: (Float, Float) -> Unit) {
onTimelinePulseList.add(callback)
}
internal fun populateBuilder(builder: Timeline.BaseBuilder<*, *, *>) {
if (this.secondaryId != null) {
builder.setSecondaryId(this.secondaryId)
}
builder.duration = this.duration
builder.setInitialDelay(this.initialDelay)
builder.setCycleDelay(this.cycleDelay)
builder.setRepeatCount(this.repeatCount)
if (this.repeatBehavior != null) {
builder.setRepeatBehavior(this.repeatBehavior)
}
if (this.name != null) {
builder.setName(this.name)
}
builder.setEase(this.ease)
for (prop in this.properties) {
val propBuilder = Timeline.property(prop.property.name)
if (prop.from == null) {
propBuilder.fromCurrent()
} else {
propBuilder.from(prop.from)
}
propBuilder.to(prop.to)
propBuilder.getWith { _, _ -> prop.property.getter.call() }
propBuilder.setWith { _, _, value -> (prop.property as? KMutableProperty)?.setter?.call(value) }
builder.addPropertyToInterpolate(propBuilder)
}
for (prop in this.propertiesGoingThrough) {
builder.addPropertyToInterpolate(Timeline.property(prop.property.name)
.goingThrough(prop.keyFrames)
.getWith { _, _ -> prop.property.getter.call() }
.setWith { _, _, value -> (prop.property as? KMutableProperty)?.setter?.call(value) })
}
for (callback in this.callbacks) {
builder.addCallback(callback)
}
if (this.onTimelineStateChangedList.isNotEmpty() || this.onTimelinePulseList.isNotEmpty()) {
builder.addCallback(object : TimelineCallbackAdapter() {
override fun onTimelineStateChanged(oldState: Timeline.TimelineState,
newState: Timeline.TimelineState, durationFraction: Float, timelinePosition: Float) {
for (callback in onTimelineStateChangedList) {
callback.invoke(oldState, newState, durationFraction, timelinePosition)
}
}
override fun onTimelinePulse(durationFraction: Float, timelinePosition: Float) {
for (callback in onTimelinePulseList) {
callback.invoke(durationFraction, timelinePosition)
}
}
})
}
}
}
public class KSwingComponentTimeline(public val component: Component) : KTimeline() {
public fun property(fromTo: PropertyFactoryFromTo<*, in Component>) {
if (fromTo.from == null) {
properties.add(fromTo.property.property(component) fromCurrentTo fromTo.to)
} else {
properties.add(fromTo.property.property(component) from fromTo.from to fromTo.to)
}
}
public fun repaintCallback() {
callback(SwingRepaintCallback(component))
}
}
public class KSwingWindowTimeline(public val window: Window) : KTimeline() {
public fun property(fromTo: PropertyFactoryFromTo<*, in Window>) {
if (fromTo.from == null) {
properties.add(fromTo.property.property(window) fromCurrentTo fromTo.to)
} else {
properties.add(fromTo.property.property(window) from fromTo.from to fromTo.to)
}
}
}
public class KSwingRepaintTimeline(public val component: Component) : KTimeline() {
public var toRepaint: Rectangle? = null
public var autoRepaintMode: Boolean = true
}
public fun timeline(property: KProperty, from: Any, to: Any): Timeline {
val builder = Timeline.Builder()
builder.addPropertyToInterpolate(Timeline.property(property.name)
.from(from)
.to(to)
.getWith { _, _ -> property.getter.call() }
.setWith { _, _, value -> (property as? KMutableProperty)?.setter?.call(value) })
return builder.build()
}
public fun timeline(property: KProperty, to: Any): Timeline {
val builder = Timeline.Builder()
builder.addPropertyToInterpolate(Timeline.property(property.name)
.fromCurrent()
.to(to)
.getWith { _, _ -> property.getter.call() }
.setWith { _, _, value -> (property as? KMutableProperty)?.setter?.call(value) })
return builder.build()
}
public fun timeline(init: KTimeline.() -> Unit): Timeline {
val timeline = KTimeline()
timeline.init()
val builder = Timeline.Builder()
timeline.populateBuilder(builder)
return builder.build()
}
public fun Any.timeline(init: KTimeline.() -> Unit): Timeline {
val timeline = KTimeline()
timeline.init()
val builder = Timeline.builder(this)
timeline.populateBuilder(builder)
return builder.build()
}
public fun Component.componentTimeline(init: KSwingComponentTimeline.() -> Unit): SwingComponentTimeline {
val timeline = KSwingComponentTimeline(this)
timeline.init()
val builder = SwingComponentTimeline.componentBuilder(this)
timeline.populateBuilder(builder)
return builder.build()
}
public fun Window.windowTimeline(init: KSwingWindowTimeline.() -> Unit): SwingComponentTimeline {
val timeline = KSwingWindowTimeline(this)
timeline.init()
val builder = SwingComponentTimeline.componentBuilder(this)
timeline.populateBuilder(builder)
return builder.build()
}
public fun Component.repaintTimeline(init: (KSwingRepaintTimeline.() -> Unit)? = null): SwingRepaintTimeline {
val timeline = KSwingRepaintTimeline(this)
if (init != null) {
timeline.init()
}
val builder = SwingRepaintTimeline.repaintBuilder(this)
timeline.populateBuilder(builder)
if (timeline.toRepaint != null) {
builder.setRepaintRectangle(timeline.toRepaint)
}
builder.setAutoRepaintMode(timeline.autoRepaintMode)
return builder.build()
}
public data class PropertyFrom(val property: KProperty, val from: R) {
public infix fun to(to: R): PropertyFromTo {
return PropertyFromTo(this.property, this.from, to)
}
}
public data class PropertyFromTo(val property: KProperty, val from: R?, val to: R)
public data class PropertyGoingThrough(val property: KProperty, val keyFrames: KeyFrames)
public infix fun KProperty.from(from: R): PropertyFrom {
return PropertyFrom(this, from)
}
public infix fun KProperty.fromCurrentTo(to: R): PropertyFromTo {
return PropertyFromTo(this, null, to)
}
public infix fun KProperty.goingThrough(keyFrames: KeyFrames): PropertyGoingThrough {
return PropertyGoingThrough(this, keyFrames)
}
public abstract class PropertyFactory {
public abstract fun property(mainObject: R): SettableProperty
public infix fun from(from: T): PropertyFactoryFrom {
return PropertyFactoryFrom(this, from)
}
public infix fun fromCurrentTo(to: T): PropertyFactoryFromTo {
return PropertyFactoryFromTo(this, null, to)
}
}
public data class PropertyFactoryFrom(val property: PropertyFactory, val from: T) {
public infix fun to(to: T): PropertyFactoryFromTo {
return PropertyFactoryFromTo(this.property, this.from, to)
}
}
public data class PropertyFactoryFromTo(val property: PropertyFactory, val from: T?, val to: T)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy