mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 04:45:13 +00:00
Add support for animating color properties
This commit is contained in:
parent
be75cb2b21
commit
b8ca0fe3c9
9 changed files with 91 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "sixtyfps_color_internal.h"
|
||||
#include "sixtyfps_properties.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -30,4 +31,25 @@ private:
|
|||
internal::types::Color inner;
|
||||
};
|
||||
|
||||
template<>
|
||||
void Property<Color>::set_animated_value(const Color &value,
|
||||
const internal::PropertyAnimation &animation_data)
|
||||
{
|
||||
internal::sixtyfps_property_set_animated_value_color(&inner, &value, &animation_data);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<typename F>
|
||||
void Property<Color>::set_animated_binding(F binding,
|
||||
const internal::PropertyAnimation &animation_data)
|
||||
{
|
||||
internal::sixtyfps_property_set_animated_binding_color(
|
||||
&inner,
|
||||
[](void *user_data, const internal::EvaluationContext *context, Color *value) {
|
||||
*reinterpret_cast<Color *>(value) = (*reinterpret_cast<F *>(user_data))(context);
|
||||
},
|
||||
new F(binding), [](void *user_data) { delete reinterpret_cast<F *>(user_data); },
|
||||
&animation_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ component ButtonRectangle := Rectangle {
|
|||
width: 100;
|
||||
height: 75;
|
||||
color: button_area.pressed ? red : button_color;
|
||||
animate color { duration: 200; }
|
||||
button_area := TouchArea {
|
||||
width: root.width;
|
||||
height: root.height;
|
||||
|
|
|
@ -40,6 +40,7 @@ component ButtonRectangle := Rectangle {
|
|||
color: black;
|
||||
}
|
||||
color: { button_area.pressed ? red : #5898; }
|
||||
animate color { duration: 500; }
|
||||
animate x {
|
||||
duration: 200;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ impl TypeRegister {
|
|||
r.property_animation_type = Type::Builtin(Rc::new(property_animation));
|
||||
r.supported_property_animation_types.insert(Type::Float32.to_string());
|
||||
r.supported_property_animation_types.insert(Type::Int32.to_string());
|
||||
r.supported_property_animation_types.insert(Type::Color.to_string());
|
||||
|
||||
r
|
||||
}
|
||||
|
|
|
@ -210,6 +210,23 @@ impl From<u32> for Color {
|
|||
}
|
||||
}
|
||||
|
||||
impl crate::abi::properties::InterpolatedPropertyValue for Color {
|
||||
fn interpolate(self, target_value: Self, t: f32) -> Self {
|
||||
Self {
|
||||
red: self.red.interpolate(target_value.red, t),
|
||||
green: self.green.interpolate(target_value.green, t),
|
||||
blue: self.blue.interpolate(target_value.blue, t),
|
||||
alpha: self.alpha.interpolate(target_value.alpha, t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Color {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "argb({}, {}, {}, {})", self.alpha, self.red, self.green, self.blue)
|
||||
}
|
||||
}
|
||||
|
||||
/// A resource is a reference to binary data, for example images. They can be accessible on the file
|
||||
/// system or embedded in the resulting binary. Or they might be URLs to a web server and a downloaded
|
||||
/// is necessary before they can be used.
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
thin dst container, and intrusive linked list
|
||||
*/
|
||||
|
||||
use crate::abi::datastructures::Color;
|
||||
use crate::abi::primitives::PropertyAnimation;
|
||||
use crate::ComponentRefPin;
|
||||
use core::cell::*;
|
||||
|
@ -485,6 +486,12 @@ impl InterpolatedPropertyValue for i32 {
|
|||
}
|
||||
}
|
||||
|
||||
impl InterpolatedPropertyValue for u8 {
|
||||
fn interpolate(self, target_value: Self, t: f32) -> Self {
|
||||
((self as f32) + (t * ((target_value as f32) - (self as f32)))).min(255.).max(0.) as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
/// PropertyAnimationBinding provides a linear animation of values of a property, when they are changed
|
||||
/// through bindings or direct set() calls.
|
||||
|
@ -672,6 +679,23 @@ pub unsafe extern "C" fn sixtyfps_property_set_animated_value_float(
|
|||
PropertyImpl::set_binding(inner.clone(), Some(animation.clone()));
|
||||
}
|
||||
|
||||
/// Internal function to set up a property animation to the specified target value for a color property.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_property_set_animated_value_color(
|
||||
out: *const PropertyHandleOpaque,
|
||||
value: &Color,
|
||||
animation_data: &crate::abi::primitives::PropertyAnimation,
|
||||
) {
|
||||
let inner = &*(out as *const PropertyHandle<Color>);
|
||||
let animation = Rc::new(RefCell::new(PropertyAnimationBinding::new_with_value(
|
||||
*value,
|
||||
animation_data,
|
||||
inner.clone(),
|
||||
)));
|
||||
|
||||
PropertyImpl::set_binding(inner.clone(), Some(animation.clone()));
|
||||
}
|
||||
|
||||
/// Internal function to set up a property animation between values produced by the specified binding for an integer property.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_int(
|
||||
|
@ -714,6 +738,27 @@ pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_float(
|
|||
PropertyImpl::set_binding(inner.clone(), Some(animation.clone()));
|
||||
}
|
||||
|
||||
/// Internal function to set up a property animation between values produced by the specified binding for a color property.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_color(
|
||||
out: *const PropertyHandleOpaque,
|
||||
binding: extern "C" fn(*mut c_void, &EvaluationContext, *mut Color),
|
||||
user_data: *mut c_void,
|
||||
drop_user_data: Option<extern "C" fn(*mut c_void)>,
|
||||
animation_data: &crate::abi::primitives::PropertyAnimation,
|
||||
) {
|
||||
let inner = &*(out as *const PropertyHandle<Color>);
|
||||
|
||||
let binding = make_c_function_binding(binding, user_data, drop_user_data);
|
||||
|
||||
let animation = Rc::new(RefCell::new(PropertyAnimationBinding::new_with_binding(
|
||||
binding,
|
||||
animation_data,
|
||||
inner.clone(),
|
||||
)));
|
||||
PropertyImpl::set_binding(inner.clone(), Some(animation.clone()));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -59,6 +59,7 @@ fn main() {
|
|||
.with_config(config.clone())
|
||||
.with_src(crate_dir.join("abi/properties.rs"))
|
||||
.with_src(crate_dir.join("abi/signals.rs"))
|
||||
.with_after_include("namespace sixtyfps { struct Color; }")
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file(include_dir.join("sixtyfps_properties_internal.h"));
|
||||
|
|
|
@ -269,7 +269,7 @@ fn generate_component(
|
|||
Type::Float32 => animated_property_info::<f32>(),
|
||||
Type::Int32 => animated_property_info::<i32>(),
|
||||
Type::String => property_info::<SharedString>(),
|
||||
Type::Color => property_info::<Color>(),
|
||||
Type::Color => animated_property_info::<Color>(),
|
||||
Type::Resource => property_info::<Resource>(),
|
||||
Type::Bool => property_info::<bool>(),
|
||||
Type::Signal => {
|
||||
|
|
|
@ -25,7 +25,8 @@ component ButtonRectangle := Rectangle {
|
|||
height: 75;
|
||||
|
||||
inner := Rectangle {
|
||||
color: root.color;
|
||||
color: { area.pressed ? green : root.color };
|
||||
animate color { duration: 500; }
|
||||
area := TouchArea {
|
||||
width: inner.width;
|
||||
height: inner.height;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue