Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 15 additions & 31 deletions api/cpp/include/slint_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,37 @@ using cbindgen_private::StateInfo;
inline void slint_property_set_animated_binding_helper(
const cbindgen_private::PropertyHandleOpaque *handle, void (*binding)(void *, int *),
void *user_data, void (*drop_user_data)(void *),
const cbindgen_private::PropertyAnimation *animation_data,
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t *))
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t **))
{
cbindgen_private::slint_property_set_animated_binding_int(
handle, binding, user_data, drop_user_data, animation_data, transition_data);
cbindgen_private::slint_property_set_animated_binding_int(handle, binding, user_data,
drop_user_data, transition_data);
}

inline void slint_property_set_animated_binding_helper(
const cbindgen_private::PropertyHandleOpaque *handle, void (*binding)(void *, float *),
void *user_data, void (*drop_user_data)(void *),
const cbindgen_private::PropertyAnimation *animation_data,
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t *))
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t **))
{
cbindgen_private::slint_property_set_animated_binding_float(
handle, binding, user_data, drop_user_data, animation_data, transition_data);
cbindgen_private::slint_property_set_animated_binding_float(handle, binding, user_data,
drop_user_data, transition_data);
}

inline void slint_property_set_animated_binding_helper(
const cbindgen_private::PropertyHandleOpaque *handle, void (*binding)(void *, Color *),
void *user_data, void (*drop_user_data)(void *),
const cbindgen_private::PropertyAnimation *animation_data,
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t *))
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t **))
{
cbindgen_private::slint_property_set_animated_binding_color(
handle, binding, user_data, drop_user_data, animation_data, transition_data);
cbindgen_private::slint_property_set_animated_binding_color(handle, binding, user_data,
drop_user_data, transition_data);
}

inline void slint_property_set_animated_binding_helper(
const cbindgen_private::PropertyHandleOpaque *handle, void (*binding)(void *, Brush *),
void *user_data, void (*drop_user_data)(void *),
const cbindgen_private::PropertyAnimation *animation_data,
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t *))
cbindgen_private::PropertyAnimation (*transition_data)(void *, uint64_t **))
{
cbindgen_private::slint_property_set_animated_binding_brush(
handle, binding, user_data, drop_user_data, animation_data, transition_data);
cbindgen_private::slint_property_set_animated_binding_brush(handle, binding, user_data,
drop_user_data, transition_data);
}

template<typename T>
Expand Down Expand Up @@ -106,21 +102,9 @@ struct Property

inline void set_animated_value(const T &value,
const cbindgen_private::PropertyAnimation &animation_data) const;
template<typename F>
inline void
set_animated_binding(F binding, const cbindgen_private::PropertyAnimation &animation_data) const
{
private_api::slint_property_set_animated_binding_helper(
&inner,
[](void *user_data, T *value) {
*reinterpret_cast<T *>(value) = (*reinterpret_cast<F *>(user_data))();
},
new F(binding), [](void *user_data) { delete reinterpret_cast<F *>(user_data); },
&animation_data, nullptr);
}

template<typename F, typename Trans>
inline void set_animated_binding_for_transition(F binding, Trans animation) const
inline void set_animated_binding(F binding, Trans animation) const
{
struct UserData
{
Expand All @@ -134,8 +118,8 @@ struct Property
reinterpret_cast<UserData *>(user_data)->binding();
},
new UserData { binding, animation },
[](void *user_data) { delete reinterpret_cast<UserData *>(user_data); }, nullptr,
[](void *user_data, uint64_t *instant) {
[](void *user_data) { delete reinterpret_cast<UserData *>(user_data); },
[](void *user_data, uint64_t **instant) {
return reinterpret_cast<UserData *>(user_data)->animation(instant);
});
}
Expand Down
23 changes: 4 additions & 19 deletions api/rs/slint/private_unstable_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,33 +67,18 @@ pub fn set_property_binding<
pub fn set_animated_property_binding<
T: Clone + i_slint_core::properties::InterpolatedPropertyValue + 'static,
StrongRef: StrongItemTreeRef + 'static,
>(
property: Pin<&Property<T>>,
component_strong: &StrongRef,
binding: fn(StrongRef) -> T,
animation_data: PropertyAnimation,
) {
let weak = component_strong.to_weak();
property.set_animated_binding(
move || binding(<StrongRef as StrongItemTreeRef>::from_weak(&weak).unwrap()),
animation_data,
)
}

pub fn set_animated_property_binding_for_transition<
T: Clone + i_slint_core::properties::InterpolatedPropertyValue + 'static,
StrongRef: StrongItemTreeRef + 'static,
>(
property: Pin<&Property<T>>,
component_strong: &StrongRef,
binding: fn(StrongRef) -> T,
compute_animation_details: fn(
StrongRef,
) -> (PropertyAnimation, i_slint_core::animations::Instant),
)
-> (PropertyAnimation, Option<i_slint_core::animations::Instant>),
) {
let weak_1 = component_strong.to_weak();
let weak_2 = weak_1.clone();
property.set_animated_binding_for_transition(
property.set_animated_binding(
move || binding(<StrongRef as StrongItemTreeRef>::from_weak(&weak_1).unwrap()),
move || {
compute_animation_details(<StrongRef as StrongItemTreeRef>::from_weak(&weak_2).unwrap())
Expand Down Expand Up @@ -186,7 +171,7 @@ pub mod re_exports {
pub use i_slint_core::accessibility::{
AccessibilityAction, AccessibleStringProperty, SupportedAccessibilityAction,
};
pub use i_slint_core::animations::{EasingCurve, animation_tick};
pub use i_slint_core::animations::{EasingCurve, animation_tick, current_tick};
pub use i_slint_core::api::{LogicalPosition, StyledText};
pub use i_slint_core::callbacks::Callback;
pub use i_slint_core::date_time::*;
Expand Down
27 changes: 17 additions & 10 deletions internal/compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,19 +669,26 @@ fn handle_property_init(
match &binding_expression.animation {
Some(llr::Animation::Static(anim)) => {
let anim = compile_expression(anim, ctx);
format!("{prop_access}.set_animated_binding({binding_code}, {anim});")
// Note: The start_time defaults to the current tick, so doesn't need to be
// udpated here.
format!("{prop_access}.set_animated_binding({binding_code},
[this](uint64_t **start_time) -> slint::cbindgen_private::PropertyAnimation {{
[[maybe_unused]] auto self = this;
auto anim = {anim};
*start_time = nullptr;
return anim;
}});",
)
}
Some(llr::Animation::Transition (
anim
)) => {
let anim = compile_expression(anim, ctx);
Some(llr::Animation::Transition(animation)) => {
let animation = compile_expression(animation, ctx);
format!(
"{prop_access}.set_animated_binding_for_transition({binding_code},
[this](uint64_t *start_time) -> slint::cbindgen_private::PropertyAnimation {{
"{prop_access}.set_animated_binding({binding_code},
[this](uint64_t **start_time) -> slint::cbindgen_private::PropertyAnimation {{
[[maybe_unused]] auto self = this;
auto [anim, time] = {anim};
*start_time = time;
return anim;
auto [animation, change_time] = {animation};
**start_time = change_time;
return animation;
}});",
)
}
Expand Down
15 changes: 10 additions & 5 deletions internal/compiler/generator/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,16 +633,21 @@ fn handle_property_init(
let anim = compile_expression(anim, ctx);
quote! { {
#init_self_pin_ref
slint::private_unstable_api::set_animated_property_binding(#rust_property, &self_rc, #binding_tokens, #anim);
slint::private_unstable_api::set_animated_property_binding(
#rust_property, &self_rc, #binding_tokens, move |self_rc| {
#init_self_pin_ref
(#anim, None)
});
} }
}
Some(llr::Animation::Transition(anim)) => {
let anim = compile_expression(anim, ctx);
Some(llr::Animation::Transition(animation)) => {
let animation = compile_expression(animation, ctx);
quote! {
slint::private_unstable_api::set_animated_property_binding_for_transition(
slint::private_unstable_api::set_animated_property_binding(
#rust_property, &self_rc, #binding_tokens, move |self_rc| {
#init_self_pin_ref
#anim
let (animation, change_time) = #animation;
(animation, Some(change_time))
}
);
}
Expand Down
2 changes: 1 addition & 1 deletion internal/compiler/llr/optim_passes/count_property_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ fn visit_binding_expression(binding: &BindingExpression, ctx: &EvaluationContext
binding.expression.borrow().visit_property_references(ctx, &mut visit_property);
match &binding.animation {
Some(Animation::Static(e) | Animation::Transition(e)) => {
e.visit_property_references(ctx, &mut visit_property)
e.visit_property_references(ctx, &mut visit_property);
}
None => (),
}
Expand Down
5 changes: 2 additions & 3 deletions internal/compiler/llr/optim_passes/remove_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,9 +501,8 @@ mod visitor {
) {
visit_expression(expression.get_mut(), scope, state, visitor);
match animation {
Some(Animation::Static(anim)) => visit_expression(anim, scope, state, visitor),
Some(Animation::Transition(anim)) => {
visit_expression(anim, scope, state, visitor);
Some(Animation::Static(anim) | Animation::Transition(anim)) => {
visit_expression(anim, scope, state, visitor)
}
None => (),
}
Expand Down
120 changes: 48 additions & 72 deletions internal/core/properties/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,10 @@ unsafe fn c_set_animated_binding<T: InterpolatedPropertyValue + Clone>(
binding: extern "C" fn(*mut c_void, *mut T),
user_data: *mut c_void,
drop_user_data: Option<extern "C" fn(*mut c_void)>,
animation_data: Option<&PropertyAnimation>,
transition_data: Option<
extern "C" fn(user_data: *mut c_void, start_instant: &mut u64) -> PropertyAnimation,
>,
transition_data: extern "C" fn(
user_data: *mut c_void,
start_instant: &mut *mut u64,
) -> PropertyAnimation,
) {
unsafe {
let binding = core::mem::transmute::<
Expand All @@ -286,27 +286,31 @@ unsafe fn c_set_animated_binding<T: InterpolatedPropertyValue + Clone>(
let animation_data = RefCell::new(properties_animations::PropertyValueAnimationData::new(
T::default(),
T::default(),
animation_data.cloned().unwrap_or_default(),
PropertyAnimation::default(),
));
if let Some(transition_data) = transition_data {
handle.0.set_binding(properties_animations::AnimatedBindingCallable::<T, _> {
original_binding,
state: Cell::new(properties_animations::AnimatedBindingState::NotAnimating),
animation_data,
compute_animation_details: move || -> properties_animations::AnimationDetail {
let mut start_instant = 0;
let anim = transition_data(user_data, &mut start_instant);
Some((anim, crate::animations::Instant(start_instant)))
},
});
} else {
handle.0.set_binding(properties_animations::AnimatedBindingCallable::<T, _> {
original_binding,
state: Cell::new(properties_animations::AnimatedBindingState::NotAnimating),
animation_data,
compute_animation_details: || -> properties_animations::AnimationDetail { None },
});
}

handle.0.set_binding(properties_animations::AnimatedBindingCallable::<T, _> {
original_binding,
state: Cell::new(properties_animations::AnimatedBindingState::NotAnimating),
animation_data,
compute_animation_details: move || -> properties_animations::AnimationDetail {
// The transition_data function receives a *mut *mut u64 pointer for the
// timestamp.
// If the function sets the pointer to nullptr, it doesn't provide a start_time.
// Otherwise, we assume it has written a value to the start_instant.
// This basically models a `&mut Option<u64>`, which is then converted to an
// `Option<Instant>`
let mut start_instant = 0u64;
let mut start_instant_ref = &mut start_instant as *mut u64;
let anim = transition_data(user_data, &mut start_instant_ref);
let start_instant = if start_instant_ref.is_null() {
None
} else {
Some(crate::animations::Instant(start_instant))
};
(anim, start_instant)
},
});
handle.0.mark_dirty();
}
}
Expand All @@ -318,20 +322,13 @@ pub unsafe extern "C" fn slint_property_set_animated_binding_int(
binding: extern "C" fn(*mut c_void, *mut core::ffi::c_int),
user_data: *mut c_void,
drop_user_data: Option<extern "C" fn(*mut c_void)>,
animation_data: Option<&PropertyAnimation>,
transition_data: Option<
extern "C" fn(user_data: *mut c_void, start_instant: &mut u64) -> PropertyAnimation,
>,
transition_data: extern "C" fn(
user_data: *mut c_void,
start_instant: &mut *mut u64,
) -> PropertyAnimation,
) {
unsafe {
c_set_animated_binding(
handle,
binding,
user_data,
drop_user_data,
animation_data,
transition_data,
);
c_set_animated_binding(handle, binding, user_data, drop_user_data, transition_data);
}
}

Expand All @@ -342,20 +339,13 @@ pub unsafe extern "C" fn slint_property_set_animated_binding_float(
binding: extern "C" fn(*mut c_void, *mut f32),
user_data: *mut c_void,
drop_user_data: Option<extern "C" fn(*mut c_void)>,
animation_data: Option<&PropertyAnimation>,
transition_data: Option<
extern "C" fn(user_data: *mut c_void, start_instant: &mut u64) -> PropertyAnimation,
>,
transition_data: extern "C" fn(
user_data: *mut c_void,
start_instant: &mut *mut u64,
) -> PropertyAnimation,
) {
unsafe {
c_set_animated_binding(
handle,
binding,
user_data,
drop_user_data,
animation_data,
transition_data,
);
c_set_animated_binding(handle, binding, user_data, drop_user_data, transition_data);
}
}

Expand All @@ -366,20 +356,13 @@ pub unsafe extern "C" fn slint_property_set_animated_binding_color(
binding: extern "C" fn(*mut c_void, *mut Color),
user_data: *mut c_void,
drop_user_data: Option<extern "C" fn(*mut c_void)>,
animation_data: Option<&PropertyAnimation>,
transition_data: Option<
extern "C" fn(user_data: *mut c_void, start_instant: &mut u64) -> PropertyAnimation,
>,
transition_data: extern "C" fn(
user_data: *mut c_void,
start_instant: &mut *mut u64,
) -> PropertyAnimation,
) {
unsafe {
c_set_animated_binding(
handle,
binding,
user_data,
drop_user_data,
animation_data,
transition_data,
);
c_set_animated_binding(handle, binding, user_data, drop_user_data, transition_data);
}
}

Expand All @@ -390,20 +373,13 @@ pub unsafe extern "C" fn slint_property_set_animated_binding_brush(
binding: extern "C" fn(*mut c_void, *mut Brush),
user_data: *mut c_void,
drop_user_data: Option<extern "C" fn(*mut c_void)>,
animation_data: Option<&PropertyAnimation>,
transition_data: Option<
extern "C" fn(user_data: *mut c_void, start_instant: &mut u64) -> PropertyAnimation,
>,
transition_data: extern "C" fn(
user_data: *mut c_void,
start_instant: &mut *mut u64,
) -> PropertyAnimation,
) {
unsafe {
c_set_animated_binding(
handle,
binding,
user_data,
drop_user_data,
animation_data,
transition_data,
);
c_set_animated_binding(handle, binding, user_data, drop_user_data, transition_data);
}
}

Expand Down
Loading
Loading