@@ -14,24 +14,20 @@ use iced::{
1414 widget:: Tree ,
1515 Clipboard , Layout , Shell , Widget ,
1616 } ,
17- alignment:: { self , Horizontal , Vertical } ,
18- event,
17+ alignment:: { self , Vertical } ,
1918 mouse:: { self , Cursor } ,
2019 touch,
2120 widget:: {
2221 text:: { self , LineHeight , Wrapping } ,
2322 Column , Row , Text ,
2423 } ,
25- Alignment , Background , Border , Color , Element , Event , Font , Length , Padding , Pixels , Point ,
24+ window , Alignment , Background , Border , Color , Element , Event , Font , Length , Padding , Pixels , Point ,
2625 Rectangle , Shadow , Size ,
2726} ;
28- use iced_fonts:: {
29- required:: { icon_to_string, RequiredIcons } ,
30- REQUIRED_FONT ,
31- } ;
3227
3328use std:: marker:: PhantomData ;
3429
30+ use crate :: iced_aw_font:: advanced_text:: cancel;
3531pub use crate :: style:: {
3632 tab_bar:: { self , Catalog , Style } ,
3733 Status , StyleFn ,
8884 tab_labels : Vec < TabLabel > ,
8985 /// The vector containing the indices of the tabs.
9086 tab_indices : Vec < TabId > ,
87+ /// The statuses of the [`TabLabel`] and cross
88+ tab_statuses : Vec < ( Option < Status > , Option < bool > ) > ,
9189 /// The function that produces the message when a tab is selected.
9290 on_select : Box < dyn Fn ( TabId ) -> Message > ,
9391 /// The function that produces the message when the close icon was pressed.
@@ -170,6 +168,7 @@ where
170168 Self {
171169 active_tab : 0 ,
172170 tab_indices : tab_labels. iter ( ) . map ( |( id, _) | id. clone ( ) ) . collect ( ) ,
171+ tab_statuses : tab_labels. iter ( ) . map ( |_| ( None , None ) ) . collect ( ) ,
173172 tab_labels : tab_labels. into_iter ( ) . map ( |( _, label) | label) . collect ( ) ,
174173 on_select : Box :: new ( on_select) ,
175174 on_close : None ,
@@ -276,6 +275,7 @@ where
276275 pub fn push ( mut self , id : TabId , tab_label : TabLabel ) -> Self {
277276 self . tab_labels . push ( tab_label) ;
278277 self . tab_indices . push ( id) ;
278+ self . tab_statuses . push ( ( None , None ) ) ;
279279 self
280280 }
281281
@@ -527,17 +527,17 @@ where
527527 . layout ( tab_tree, renderer, & limits. loose ( ) )
528528 }
529529
530- fn on_event (
530+ fn update (
531531 & mut self ,
532532 _state : & mut Tree ,
533- event : Event ,
533+ event : & Event ,
534534 layout : Layout < ' _ > ,
535535 cursor : Cursor ,
536536 _renderer : & Renderer ,
537537 _clipboard : & mut dyn Clipboard ,
538538 shell : & mut Shell < ' _ , Message > ,
539539 _viewport : & Rectangle ,
540- ) -> event :: Status {
540+ ) {
541541 match event {
542542 Event :: Mouse ( mouse:: Event :: ButtonPressed ( mouse:: Button :: Left ) )
543543 | Event :: Touch ( touch:: Event :: FingerPressed { .. } ) => {
@@ -569,12 +569,44 @@ where
569569 |on_close| ( on_close) ( self . tab_indices [ new_selected] . clone ( ) ) ,
570570 ) ,
571571 ) ;
572- return event :: Status :: Captured ;
572+ shell . capture_event ( ) ;
573573 }
574574 }
575- event:: Status :: Ignored
576575 }
577- _ => event:: Status :: Ignored ,
576+ _ => { }
577+ }
578+
579+ let mut request_redraw = false ;
580+ let children = layout. children ( ) ;
581+ for ( ( i, _tab) , layout) in self . tab_labels . iter ( ) . enumerate ( ) . zip ( children) {
582+ let active_idx = self . get_active_tab_idx ( ) ;
583+ let tab_status = self . tab_statuses . get_mut ( i) . expect ( "Should have a status." ) ;
584+
585+ let current_status = if cursor. is_over ( layout. bounds ( ) ) {
586+ Status :: Hovered
587+ } else if i == active_idx {
588+ Status :: Active
589+ } else {
590+ Status :: Disabled
591+ } ;
592+
593+ let mut is_cross_hovered = None ;
594+ let mut children = layout. children ( ) ;
595+ if let Some ( cross_layout) = children. next_back ( ) {
596+ is_cross_hovered = Some ( cursor. is_over ( cross_layout. bounds ( ) ) ) ;
597+ }
598+
599+ if let Event :: Window ( window:: Event :: RedrawRequested ( _now) ) = event {
600+ * tab_status = ( Some ( current_status) , is_cross_hovered) ;
601+ } else if tab_status. 0 . is_some_and ( |status| status != current_status)
602+ || tab_status. 1 != is_cross_hovered
603+ {
604+ request_redraw = true ;
605+ }
606+ }
607+
608+ if request_redraw {
609+ shell. request_redraw ( ) ;
578610 }
579611 }
580612
@@ -636,24 +668,29 @@ where
636668 color : style_sheet. border_color . unwrap_or ( Color :: TRANSPARENT ) ,
637669 } ,
638670 shadow : Shadow :: default ( ) ,
671+ ..renderer:: Quad :: default ( )
639672 } ,
640673 style_sheet
641674 . background
642675 . unwrap_or_else ( || Color :: TRANSPARENT . into ( ) ) ,
643676 ) ;
644677 }
645678
679+ let ( _content, font, _shaping) = cancel ( ) ;
680+
646681 for ( ( i, tab) , layout) in self . tab_labels . iter ( ) . enumerate ( ) . zip ( children) {
682+ let tab_status = self . tab_statuses . get ( i) . expect ( "Should have a status." ) ;
683+
647684 draw_tab (
648685 renderer,
649686 tab,
687+ tab_status,
650688 layout,
651689 self . position ,
652690 theme,
653691 & self . class ,
654- i == self . get_active_tab_idx ( ) ,
655692 cursor,
656- ( self . font . unwrap_or ( REQUIRED_FONT ) , self . icon_size ) ,
693+ ( self . font . unwrap_or ( font ) , self . icon_size ) ,
657694 ( self . text_font . unwrap_or_default ( ) , self . text_size ) ,
658695 self . close_size ,
659696 viewport,
@@ -671,12 +708,12 @@ where
671708fn draw_tab < Theme , Renderer > (
672709 renderer : & mut Renderer ,
673710 tab : & TabLabel ,
711+ tab_status : & ( Option < Status > , Option < bool > ) ,
674712 layout : Layout < ' _ > ,
675713 position : Position ,
676714 theme : & Theme ,
677715 class : & <Theme as Catalog >:: Class < ' _ > ,
678- is_selected : bool ,
679- cursor : Cursor ,
716+ _cursor : Cursor ,
680717 icon_data : ( Font , f32 ) ,
681718 text_data : ( Font , f32 ) ,
682719 close_size : f32 ,
@@ -696,15 +733,8 @@ fn draw_tab<Theme, Renderer>(
696733 }
697734
698735 let bounds = layout. bounds ( ) ;
699- let is_mouse_over = cursor. position ( ) . is_some_and ( |pos| bounds. contains ( pos) ) ;
700-
701- let style = if is_mouse_over {
702- tab_bar:: Catalog :: style ( theme, class, Status :: Hovered )
703- } else if is_selected {
704- tab_bar:: Catalog :: style ( theme, class, Status :: Active )
705- } else {
706- tab_bar:: Catalog :: style ( theme, class, Status :: Disabled )
707- } ;
736+
737+ let style = tab_bar:: Catalog :: style ( theme, class, tab_status. 0 . unwrap_or ( Status :: Disabled ) ) ;
708738
709739 let mut children = layout. children ( ) ;
710740 let label_layout = children
@@ -722,6 +752,7 @@ fn draw_tab<Theme, Renderer>(
722752 color : style. tab_label_border_color ,
723753 } ,
724754 shadow : Shadow :: default ( ) ,
755+ ..renderer:: Quad :: default ( )
725756 } ,
726757 style. tab_label_background ,
727758 ) ;
@@ -737,8 +768,8 @@ fn draw_tab<Theme, Renderer>(
737768 bounds : Size :: new ( icon_bounds. width , icon_bounds. height ) ,
738769 size : Pixels ( icon_data. 1 ) ,
739770 font : icon_data. 0 ,
740- horizontal_alignment : Horizontal :: Center ,
741- vertical_alignment : Vertical :: Center ,
771+ align_x : text :: Alignment :: Center ,
772+ align_y : Vertical :: Center ,
742773 line_height : LineHeight :: Relative ( 1.3 ) ,
743774 shaping : iced:: advanced:: text:: Shaping :: Advanced ,
744775 wrapping : Wrapping :: default ( ) ,
@@ -758,8 +789,8 @@ fn draw_tab<Theme, Renderer>(
758789 bounds : Size :: new ( text_bounds. width , text_bounds. height ) ,
759790 size : Pixels ( text_data. 1 ) ,
760791 font : text_data. 0 ,
761- horizontal_alignment : Horizontal :: Center ,
762- vertical_alignment : Vertical :: Center ,
792+ align_x : text :: Alignment :: Center ,
793+ align_y : Vertical :: Center ,
763794 line_height : LineHeight :: Relative ( 1.3 ) ,
764795 shaping : iced:: advanced:: text:: Shaping :: Advanced ,
765796 wrapping : Wrapping :: default ( ) ,
@@ -806,8 +837,8 @@ fn draw_tab<Theme, Renderer>(
806837 bounds : Size :: new ( icon_bounds. width , icon_bounds. height ) ,
807838 size : Pixels ( icon_data. 1 ) ,
808839 font : icon_data. 0 ,
809- horizontal_alignment : Horizontal :: Center ,
810- vertical_alignment : Vertical :: Center ,
840+ align_x : text :: Alignment :: Center ,
841+ align_y : Vertical :: Center ,
811842 line_height : LineHeight :: Relative ( 1.3 ) ,
812843 shaping : iced:: advanced:: text:: Shaping :: Advanced ,
813844 wrapping : Wrapping :: default ( ) ,
@@ -823,8 +854,8 @@ fn draw_tab<Theme, Renderer>(
823854 bounds : Size :: new ( text_bounds. width , text_bounds. height ) ,
824855 size : Pixels ( text_data. 1 ) ,
825856 font : text_data. 0 ,
826- horizontal_alignment : Horizontal :: Center ,
827- vertical_alignment : Vertical :: Center ,
857+ align_x : text :: Alignment :: Center ,
858+ align_y : Vertical :: Center ,
828859 line_height : LineHeight :: Relative ( 1.3 ) ,
829860 shaping : iced:: advanced:: text:: Shaping :: Advanced ,
830861 wrapping : Wrapping :: default ( ) ,
@@ -838,18 +869,20 @@ fn draw_tab<Theme, Renderer>(
838869
839870 if let Some ( cross_layout) = children. next ( ) {
840871 let cross_bounds = cross_layout. bounds ( ) ;
841- let is_mouse_over_cross = cursor. is_over ( cross_bounds) ;
872+ let is_mouse_over_cross = tab_status. 1 . unwrap_or ( false ) ;
873+
874+ let ( content, font, shaping) = cancel ( ) ;
842875
843876 renderer. fill_text (
844877 iced:: advanced:: text:: Text {
845- content : icon_to_string ( RequiredIcons :: X ) ,
878+ content,
846879 bounds : Size :: new ( cross_bounds. width , cross_bounds. height ) ,
847880 size : Pixels ( close_size + if is_mouse_over_cross { 1.0 } else { 0.0 } ) ,
848- font : REQUIRED_FONT ,
849- horizontal_alignment : Horizontal :: Center ,
850- vertical_alignment : Vertical :: Center ,
881+ font,
882+ align_x : text :: Alignment :: Center ,
883+ align_y : Vertical :: Center ,
851884 line_height : LineHeight :: Relative ( 1.3 ) ,
852- shaping : iced :: advanced :: text :: Shaping :: Advanced ,
885+ shaping,
853886 wrapping : Wrapping :: default ( ) ,
854887 } ,
855888 Point :: new ( cross_bounds. center_x ( ) , cross_bounds. center_y ( ) ) ,
@@ -867,6 +900,7 @@ fn draw_tab<Theme, Renderer>(
867900 color : style. border_color . unwrap_or ( Color :: TRANSPARENT ) ,
868901 } ,
869902 shadow : Shadow :: default ( ) ,
903+ ..renderer:: Quad :: default ( )
870904 } ,
871905 style
872906 . icon_background
0 commit comments