@@ -44,6 +44,7 @@ const SYSTEM_MONO_FONT_PATHS: &[&str] = &[
4444] ;
4545const LANGUAGE_OPTIONS : [ AppLanguage ; 2 ] = [ AppLanguage :: Chinese , AppLanguage :: English ] ;
4646const STEPPER_DOT_SIZE : u16 = 6 ;
47+ const STEPPER_ACTIVE_DOT_SIZE : u16 = 18 ;
4748const STEPPER_LINE_HEIGHT : u16 = 1 ;
4849const STEPPER_NODE_WIDTH : u16 = 112 ;
4950const STEPPER_EDGE_INSET : u16 = 0 ;
@@ -1295,12 +1296,12 @@ fn install_stage_stepper(
12951296 let left_connector = if index == 0 {
12961297 None
12971298 } else {
1298- Some ( stage_connector_state ( states[ index - 1 ] ) )
1299+ Some ( completed_connector_state ( states[ index - 1 ] ) )
12991300 } ;
13001301 let right_connector = if index + 1 == titles. len ( ) {
13011302 None
13021303 } else {
1303- Some ( stage_connector_state ( states[ index] ) )
1304+ Some ( completed_connector_state ( states[ index] ) )
13041305 } ;
13051306
13061307 track = track. push ( install_stage_node (
@@ -1312,7 +1313,7 @@ fn install_stage_stepper(
13121313 labels = labels. push ( install_stage_label_node ( titles[ index] , states[ index] , dark) ) ;
13131314
13141315 if index + 1 < titles. len ( ) {
1315- let connector_state = stage_connector_state ( states[ index] ) ;
1316+ let connector_state = completed_connector_state ( states[ index] ) ;
13161317 track = track. push ( install_stage_segment ( connector_state) ) ;
13171318 labels = labels. push ( install_stage_gap ( ) ) ;
13181319 }
@@ -1328,9 +1329,9 @@ fn install_stage_stepper(
13281329 . into ( )
13291330}
13301331
1331- fn stage_connector_state ( state : StepVisualState ) -> StepVisualState {
1332- if matches ! ( state, StepVisualState :: Done | StepVisualState :: Active ) {
1333- state
1332+ fn completed_connector_state ( state : StepVisualState ) -> StepVisualState {
1333+ if matches ! ( state, StepVisualState :: Done ) {
1334+ StepVisualState :: Done
13341335 } else {
13351336 StepVisualState :: Pending
13361337 }
@@ -1357,6 +1358,21 @@ fn install_stage_node(
13571358}
13581359
13591360fn install_stage_dot ( state : StepVisualState , spinner_frame : usize ) -> Element < ' static , Message > {
1361+ if state == StepVisualState :: Active {
1362+ return container (
1363+ container ( text ( "" ) )
1364+ . width ( STEPPER_DOT_SIZE )
1365+ . height ( STEPPER_DOT_SIZE )
1366+ . style ( move |theme| step_dot_style ( theme, state, spinner_frame) ) ,
1367+ )
1368+ . width ( STEPPER_ACTIVE_DOT_SIZE )
1369+ . height ( STEPPER_ACTIVE_DOT_SIZE )
1370+ . align_x ( iced:: alignment:: Horizontal :: Center )
1371+ . align_y ( iced:: alignment:: Vertical :: Center )
1372+ . style ( move |theme| active_step_dot_ring_style ( theme, spinner_frame) )
1373+ . into ( ) ;
1374+ }
1375+
13601376 container ( text ( "" ) )
13611377 . width ( STEPPER_DOT_SIZE )
13621378 . height ( STEPPER_DOT_SIZE )
@@ -1489,6 +1505,10 @@ fn contains_cjk(value: &str) -> bool {
14891505}
14901506
14911507fn terminal_log_line ( log : & str ) -> String {
1508+ if is_terminal_error_log ( log) && !is_terminal_stderr_log ( log) {
1509+ return format ! ( "! {}" , compact_terminal_paths( log) ) ;
1510+ }
1511+
14921512 if let Some ( command) = log
14931513 . strip_prefix ( "执行命令:" )
14941514 . or_else ( || log. strip_prefix ( "Running: " ) )
@@ -1507,7 +1527,7 @@ fn terminal_log_line(log: &str) -> String {
15071527 . strip_prefix ( "错误输出:" )
15081528 . or_else ( || log. strip_prefix ( "stderr: " ) )
15091529 {
1510- return format ! ( "! {}" , compact_terminal_paths( output) ) ;
1530+ return format ! ( "~ {}" , compact_terminal_paths( output) ) ;
15111531 }
15121532
15131533 format ! ( "# {}" , compact_terminal_paths( log) )
@@ -1530,17 +1550,18 @@ fn terminal_log_color(log: &str, dark: bool) -> Color {
15301550 } ;
15311551 }
15321552
1533- if log. starts_with ( "错误输出:" )
1534- || log. starts_with ( "stderr: " )
1535- || log. starts_with ( "Failed to open " )
1536- {
1553+ if is_terminal_error_log ( log) && !is_terminal_stderr_log ( log) {
15371554 return if dark {
15381555 Color :: from_rgb8 ( 0xFF , 0xA3 , 0x91 )
15391556 } else {
15401557 Color :: from_rgb8 ( 0xB2 , 0x47 , 0x38 )
15411558 } ;
15421559 }
15431560
1561+ if is_terminal_stderr_log ( log) {
1562+ return terminal_warning_color ( dark) ;
1563+ }
1564+
15441565 if log. starts_with ( "输出:" ) || log. starts_with ( "stdout: " ) {
15451566 return if dark {
15461567 Color :: from_rgb8 ( 0xC9 , 0xD3 , 0xDF )
@@ -1552,6 +1573,27 @@ fn terminal_log_color(log: &str, dark: bool) -> Color {
15521573 terminal_muted_color ( dark)
15531574}
15541575
1576+ fn is_terminal_stderr_log ( log : & str ) -> bool {
1577+ log. starts_with ( "错误输出:" ) || log. starts_with ( "stderr: " )
1578+ }
1579+
1580+ fn is_terminal_error_log ( log : & str ) -> bool {
1581+ let lower = log. to_ascii_lowercase ( ) ;
1582+ log. starts_with ( "Failed to open " )
1583+ || lower. starts_with ( "failed " )
1584+ || lower. starts_with ( "error:" )
1585+ || lower. contains ( " failed:" )
1586+ || lower. contains ( " failed to " )
1587+ }
1588+
1589+ fn terminal_warning_color ( dark : bool ) -> Color {
1590+ if dark {
1591+ Color :: from_rgb8 ( 0xFF , 0xCE , 0x73 )
1592+ } else {
1593+ Color :: from_rgb8 ( 0x9B , 0x61 , 0x00 )
1594+ }
1595+ }
1596+
15551597fn terminal_muted_color ( dark : bool ) -> Color {
15561598 if dark {
15571599 Color :: from_rgb8 ( 0xA9 , 0xB5 , 0xC2 )
@@ -1921,17 +1963,36 @@ fn stepper_card_style(theme: &Theme) -> container::Style {
19211963
19221964fn step_dot_style ( theme : & Theme , state : StepVisualState , spinner_frame : usize ) -> container:: Style {
19231965 let is_dark = theme. extended_palette ( ) . is_dark ;
1924- let mut color = step_color ( state, is_dark) ;
1925-
1926- if state == StepVisualState :: Active && spinner_frame % 6 >= 3 {
1927- color. a = 0.45 ;
1928- }
1966+ let _ = spinner_frame;
1967+ let color = step_color ( state, is_dark) ;
19291968
19301969 container:: Style :: default ( )
19311970 . background ( color)
19321971 . border ( border:: rounded ( 999 ) )
19331972}
19341973
1974+ fn active_step_dot_ring_style ( theme : & Theme , spinner_frame : usize ) -> container:: Style {
1975+ let is_dark = theme. extended_palette ( ) . is_dark ;
1976+ let accent = step_color ( StepVisualState :: Active , is_dark) ;
1977+ let alpha = match ( spinner_frame / 4 ) % 3 {
1978+ 0 => 0.12 ,
1979+ 1 => 0.22 ,
1980+ _ => 0.32 ,
1981+ } ;
1982+ let border_alpha = if is_dark { 0.95 } else { 0.78 } ;
1983+
1984+ container:: Style :: default ( )
1985+ . background ( Color { a : alpha, ..accent } )
1986+ . border (
1987+ border:: rounded ( 999 )
1988+ . color ( Color {
1989+ a : border_alpha,
1990+ ..accent
1991+ } )
1992+ . width ( 1.0 ) ,
1993+ )
1994+ }
1995+
19351996fn step_connector_style ( theme : & Theme , state : StepVisualState ) -> container:: Style {
19361997 let is_dark = theme. extended_palette ( ) . is_dark ;
19371998 let color = match state {
0 commit comments