I just published `0.10.2-SNAPSHOT`. Please try it ...
# doodle
n
I just published
0.10.2-SNAPSHOT
. Please try it out (and provide feedback) by pointing to
maven { url = uri("<https://oss.sonatype.org/content/repositories/snapshots>") }
. Here's what's included so far... Animation Chaining Animations can now be chained within an animation block using the new
then
method. This makes it easier to have sequential animations and avoids the need to explicitly track secondary animations for cancellation, since these are tied to their "parent" animation.
Copy code
// val animate: Animator

val animation = animate {
    0f to 1f using (tweenFloat(easing, duration)) {                   // (1)
        // ...
    } then {
        0f to 1f using (after(delay, tweenFloat(easing, duration))) { // (2)

        } then {                                                      // (3)
            // ...
        }
    } then {                                                          // (4)
        // ...
    }
}

animation.completed += { /* ... */ }  // applies to entire chain
animation.pause ()                    // applies to entire chain
animation.cancel()                    // applies to entire chain
Desktop Accessibility Support Doodle's web apps have had accessibility support for some time. Now those capabilities are available for desktop apps as well. You simply include the
AccessibilityModule
in your app and follow the guidelines of how to add roles, labels, etc. to your Views. SpinButton Accessibility `SpinButton`s now use the new
SpinButtonRole
that allows assistive tools to better read them. This role exposes the currently selected value based on a new
valueAccessibilityLabeler
function that converts the value to a
String
. Improved Sliders Sliders can now represent values of any
Comparable
type
T
between two
start
and
end
values. This is possible for `T`s that have some interpolation between a
start
and
end
based on some value between
0
and
1
. This is done via a new
TypeConverter<T>
that defines the interpolation (and its inverse). This means you can now create sliders for numeric types like
Measure<T>
directly and their
value
will by of the right type.
Copy code
val charSlider     = Slider('A' .. 'Z')
val velocitySlider = Slider(10 * meters / seconds .. 100 * miles / hours)
You can also create Sliders for any type
T
, as long as it is
Comparable
and you can create an
Interpolator
for it.
Copy code
fun <T: Comparable<T>> customSlider(model: ConfinedValueModel<T>, interpolator: Interpolator<T>) {
    val slider: Slider<T> = Slider(model, interpolator = interpolator)
}
These, more flexible Sliders can also be used in forms as expected.
Copy code
Form {this(
    + slider('A' .. 'Z'),
    + slider(10 * meters/seconds .. 10 * miles/hours),
    + slider(model, interpolator = interpolator),
    onInvalid = {}
) { _: Char, _: Measure<Velocity>, _: T ->

}}
Non-linear Sliders Sliders are linear by default, which means a change in their position translates to a linear change in their value. There are cases however, when it makes sense to have a slider's value change in a non-linear way. You can do this by providing a function that maps values between the slider's input and output spaces. These values are all within the [0-1] domain, and work very similarly to easing functions used for animations. The big difference is they have two forms: f(x) and f^-1(x).
Copy code
import io.nacular.doodle.controls.range.InvertibleFunction
import io.nacular.doodle.controls.range.Slider
import kotlin.math.log
import kotlin.math.pow

/**
 * Logarithmic function and inverse <https://www.desmos.com/calculator/qq59ey0bub>
 */
private object LogFunction: InvertibleFunction {
    override fun invoke (value: Float) = log((10f - 1) * value + 1, 10f)
    override fun inverse(value: Float) = (10f.pow(value) - 1)/(10 - 1)
}

val logarithmicSlider = Slider(0.0 .. 1.0, function = LogFunction)
APIs • General ◦ New
after
animation function that allows a delay before executing an
AnimationPlan
. ◦ Made
Scene
a public type since it is part of the public API for
Theme
◦ New builders for creating Sliders for
Char
and
Measure<T>
◦ New
increment
and
decrement
methods for sliders ◦ New methods for incrementing/decrementing start/end for
RangeValueSlider
◦ Renamed
Spinner
to
SpinButton
(and related classes) and deprecated all old uses. ◦ New
SpinButtonRole
for accessibility. ◦
ThemePicker
now allows customization of accessible value labels via new
valueAccessibilityLabeler
property. ◦
ListItemRole
now has a
selected
state.
ListItem
(BasicTheme) now keeps this value up-to-date. ◦ New
circumference
extension for
Circle
◦ New helper for calculating the interior angle between two
Vector3D
instances. ◦ New form methods for creating
SpinButton
form controls from a
List
of values or
IntProgression
. ◦ New functions for creating ease[In/Out]Bounce EasingFunctions with an `initialBounceFraction`:
easeIn(0.15f)
. ◦ New convenience methods for working with PathBuilders using x,y instead of Point. • Deprecations ◦ All animation functions that take a delay, since there is a new
after
function. ◦ Types and functions related to
Spinner
, which was renamed to
SpinButton
. ◦ Types and functions related to
Dropdown
, which was renamed to
SelectBox
. Fixes | Improvements • General ◦ Issue where item could be stuck in render loop if it requires a layout, but cannot render b/c it is not recursively visible (it and all ancestors visible). • Browser ◦ Fixed issue with Display pointer exit not being properly handled. ◦ Work-around for Safari giving incorrect clientX/Y values when the browser window is zoomed, which broke pointer location. ◦ Fixed edge case where old rendered vectors aren't cleaned up if a sub-frame happens where one wasn't before. ◦ Fixed bug in reading items from DataTransferItemList that broke file drag-drop Versions • Kotlin -> 1.9.23 • Kover -> 0.8.1 • Dokka -> 1.9.20
alphabet yellow d 2
🎉 2
c
Hi nick, great job 👏🏿 .
❤️ 1