@@ -12,7 +12,7 @@ use cosmic::iced_core::{
1212} ;
1313use cosmic:: iced_widget:: { Row , Text } ;
1414
15- use crate :: keyframes :: { self , toggler:: Chain } ;
15+ use crate :: { chain , id , lerp , toggler} ;
1616pub use cosmic:: iced_style:: toggler:: { Appearance , StyleSheet } ;
1717
1818/// The default animation duration. Change here for custom widgets. Or at runtime with `.anim_multiplier`
4040 Renderer : text:: Renderer ,
4141 Renderer :: Theme : StyleSheet ,
4242{
43- id : crate :: keyframes :: toggler :: Id ,
43+ id : id :: Toggler ,
4444 is_toggled : bool ,
45- on_toggle : Box < dyn Fn ( Chain , bool ) -> Message + ' a > ,
45+ on_toggle : Box < dyn Fn ( chain :: Toggler , bool ) -> Message + ' a > ,
4646 label : Option < String > ,
4747 width : Length ,
4848 size : f32 ,
7373 /// * a function that will be called when the [`Toggler`] is toggled. It
7474 /// will receive the new state of the [`Toggler`] and must produce a
7575 /// `Message`.
76- pub fn new < F > (
77- id : crate :: keyframes:: toggler:: Id ,
78- label : impl Into < Option < String > > ,
79- is_toggled : bool ,
80- f : F ,
81- ) -> Self
76+ pub fn new < F > ( id : id:: Toggler , label : impl Into < Option < String > > , is_toggled : bool , f : F ) -> Self
8277 where
83- F : ' a + Fn ( Chain , bool ) -> Message ,
78+ F : ' a + Fn ( chain :: Toggler , bool ) -> Message ,
8479 {
8580 Toggler {
8681 id,
@@ -221,25 +216,20 @@ where
221216 // TODO this should be possible to fix once redirectable
222217 // animations are implemented.
223218 if mouse_over && ( self . percent == 0.0 || self . percent == 1.0 ) {
219+ let duration = ( ANIM_DURATION * self . anim_multiplier . round ( ) ) as u64 ;
224220 if self . is_toggled {
225- let off_animation = Chain :: new ( self . id . clone ( ) )
226- . link ( keyframes:: toggler:: Toggler :: new ( Duration :: ZERO ) . percent ( 1.0 ) )
227- . link (
228- keyframes:: toggler:: Toggler :: new ( Duration :: from_millis (
229- ( ANIM_DURATION * self . anim_multiplier . round ( ) ) as u64 ,
230- ) )
231- . percent ( 0.0 ) ,
232- ) ;
221+ let off_animation = chain ! (
222+ self . id. clone( ) ,
223+ toggler( Duration :: ZERO ) . percent( 1.0 ) ,
224+ toggler( Duration :: from_millis( duration) ) . percent( 0.0 ) ,
225+ ) ;
233226 shell. publish ( ( self . on_toggle ) ( off_animation, !self . is_toggled ) ) ;
234227 } else {
235- let on_animation = Chain :: new ( self . id . clone ( ) )
236- . link ( keyframes:: toggler:: Toggler :: new ( Duration :: ZERO ) . percent ( 0.0 ) )
237- . link (
238- keyframes:: toggler:: Toggler :: new ( Duration :: from_millis (
239- ( ANIM_DURATION * self . anim_multiplier . round ( ) ) as u64 ,
240- ) )
241- . percent ( 1.0 ) ,
242- ) ;
228+ let on_animation = chain ! (
229+ self . id. clone( ) ,
230+ toggler( Duration :: ZERO ) . percent( 0.0 ) ,
231+ toggler( Duration :: from_millis( duration) ) . percent( 1.0 ) ,
232+ ) ;
243233 shell. publish ( ( self . on_toggle ) ( on_animation, !self . is_toggled ) ) ;
244234 }
245235
@@ -310,9 +300,17 @@ where
310300 let is_mouse_over = bounds. contains ( cursor_position) ;
311301
312302 let style = if is_mouse_over {
313- theme. hovered ( & self . style , self . is_toggled )
303+ blend_appearances (
304+ theme. hovered ( & self . style , false ) ,
305+ theme. hovered ( & self . style , true ) ,
306+ self . percent ,
307+ )
314308 } else {
315- theme. active ( & self . style , self . is_toggled )
309+ blend_appearances (
310+ theme. active ( & self . style , false ) ,
311+ theme. active ( & self . style , true ) ,
312+ self . percent ,
313+ )
316314 } ;
317315
318316 let border_radius = bounds. height / BORDER_RADIUS_RATIO ;
@@ -337,11 +335,11 @@ where
337335
338336 let toggler_foreground_bounds = Rectangle {
339337 x : bounds. x
340- + if self . is_toggled {
341- bounds . width - 2.0 * space - ( bounds . height - ( 4.0 * space ) )
342- } else {
343- 2.0 * space
344- } ,
338+ + lerp (
339+ 2.0 * space,
340+ bounds . width - 2.0 * space - ( bounds . height - ( 4.0 * space ) ) ,
341+ self . percent ,
342+ ) ,
345343 y : bounds. y + ( 2.0 * space) ,
346344 width : bounds. height - ( 4.0 * space) ,
347345 height : bounds. height - ( 4.0 * space) ,
@@ -369,3 +367,24 @@ where
369367 Element :: new ( toggler)
370368 }
371369}
370+
371+ fn blend_appearances ( one : Appearance , mut two : Appearance , percent : f32 ) -> Appearance {
372+ if percent == 0. {
373+ one
374+ } else if percent == 1. {
375+ two
376+ } else {
377+ let background: [ f32 ; 4 ] = one
378+ . background
379+ . into_linear ( )
380+ . iter ( )
381+ . zip ( two. background . into_linear ( ) . iter ( ) )
382+ . map ( |( o, t) | o * ( 1.0 - percent) + t * percent)
383+ . collect :: < Vec < f32 > > ( )
384+ . try_into ( )
385+ . unwrap ( ) ;
386+
387+ two. background = background. into ( ) ;
388+ two
389+ }
390+ }
0 commit comments