11use crate :: {
22 constants:: TRANSFORMS ,
33 state:: { App , Panel } ,
4- tui:: key_binds:: { get_monitor_keybinds, get_scale_keybinds, get_transform_keybinds} ,
4+ tui:: key_binds:: {
5+ get_monitor_keybinds, get_scale_keybinds, get_transform_keybinds,
6+ } ,
57 utils:: { self , effective_dimensions, monitor_resolution, transform_label} ,
68} ;
79
@@ -10,7 +12,7 @@ use ratatui::{
1012 layout:: { Constraint , Direction , Layout , Rect } ,
1113 style:: { Color , Modifier , Style } ,
1214 text:: { Line , Span } ,
13- widgets:: { Block , BorderType , Borders , List , ListItem , Paragraph } ,
15+ widgets:: { Block , BorderType , Borders , Clear , List , ListItem , Paragraph } ,
1416} ;
1517use wlx_monitors:: WlTransform ;
1618
@@ -98,7 +100,10 @@ fn render_map(frame: &mut Frame, app: &App, area: Rect) {
98100 format!( "{}×{} " , ew, eh) ,
99101 Style :: default ( ) . fg( Color :: White ) ,
100102 ) ,
101- Span :: styled( format!( "({},{}) " , dx, dy) , Style :: default ( ) . fg( pos_color) ) ,
103+ Span :: styled(
104+ format!( "({},{}) " , dx, dy) ,
105+ Style :: default ( ) . fg( pos_color) ,
106+ ) ,
102107 Span :: styled(
103108 format!( "{}× " , monitor. scale) ,
104109 Style :: default ( ) . fg( Color :: White ) ,
@@ -132,9 +137,14 @@ fn render_map(frame: &mut Frame, app: &App, area: Rect) {
132137 ) ,
133138 Span :: styled(
134139 "OFF " ,
135- Style :: default ( ) . fg( Color :: Red ) . add_modifier( Modifier :: BOLD ) ,
140+ Style :: default ( )
141+ . fg( Color :: Red )
142+ . add_modifier( Modifier :: BOLD ) ,
143+ ) ,
144+ Span :: styled(
145+ "— t to enable" ,
146+ Style :: default ( ) . fg( Color :: DarkGray ) ,
136147 ) ,
137- Span :: styled( "— t to enable" , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
138148 ] ) ) ;
139149 }
140150 } else {
@@ -144,7 +154,11 @@ fn render_map(frame: &mut Frame, app: &App, area: Rect) {
144154 frame. render_widget ( Paragraph :: new ( lines) , inner) ;
145155}
146156
147- fn build_layout_map < ' a > ( app : & App , width : usize , height : usize ) -> Vec < Line < ' a > > {
157+ fn build_layout_map < ' a > (
158+ app : & App ,
159+ width : usize ,
160+ height : usize ,
161+ ) -> Vec < Line < ' a > > {
148162 let monitors = & app. monitors ;
149163 let selected_idx = app. selected_monitor ;
150164 let zoom = app. map_zoom ;
@@ -252,7 +266,8 @@ fn build_layout_map<'a>(app: &App, width: usize, height: usize) -> Vec<Line<'a>>
252266 let cx = pad + ( ( rect. px - min_x) as f64 / ppc) as usize ;
253267 let cy = ( ( rect. py - min_y) as f64 / ( ppc * CHAR_ASPECT ) ) as usize ;
254268 let cw = ( rect. pw as f64 / ppc) . round ( ) . max ( 1.0 ) as usize ;
255- let ch = ( rect. ph as f64 / ( ppc * CHAR_ASPECT ) ) . round ( ) . max ( 1.0 ) as usize ;
269+ let ch =
270+ ( rect. ph as f64 / ( ppc * CHAR_ASPECT ) ) . round ( ) . max ( 1.0 ) as usize ;
256271
257272 let x1 = cx. min ( width. saturating_sub ( 1 ) ) ;
258273 let y1 = cy. min ( height. saturating_sub ( 1 ) ) ;
@@ -344,11 +359,13 @@ fn build_layout_map<'a>(app: &App, width: usize, height: usize) -> Vec<Line<'a>>
344359 break ;
345360 }
346361 let truncated: String = text. chars ( ) . take ( inner_w) . collect ( ) ;
347- let text_start = x1 + 1 + inner_w. saturating_sub ( truncated. len ( ) ) / 2 ;
362+ let text_start =
363+ x1 + 1 + inner_w. saturating_sub ( truncated. len ( ) ) / 2 ;
348364 for ( j, ch) in truncated. chars ( ) . enumerate ( ) {
349365 let col = text_start + j;
350366 if col < x2 - 1 {
351- grid[ row] [ col] = ( ch, text_fg, * bold || rect. is_selected ) ;
367+ grid[ row] [ col] =
368+ ( ch, text_fg, * bold || rect. is_selected ) ;
352369 }
353370 }
354371 }
@@ -529,3 +546,101 @@ fn render_transform(frame: &mut Frame, app: &mut App, area: Rect) {
529546
530547 frame. render_stateful_widget ( list, area, & mut app. transform_state ) ;
531548}
549+
550+ pub fn render_warning_modal ( frame : & mut Frame , area : Rect , config_path : & str ) {
551+ let path_w = config_path. len ( ) as u16 + 14 ;
552+ let modal_w = path_w. max ( 48 ) . min ( area. width . saturating_sub ( 4 ) ) ;
553+ let modal_h = 15u16 . min ( area. height . saturating_sub ( 2 ) ) ;
554+ let x = ( area. width . saturating_sub ( modal_w) ) / 2 ;
555+ let y = ( area. height . saturating_sub ( modal_h) ) / 2 ;
556+ let modal_area = Rect :: new ( x, y, modal_w, modal_h) ;
557+
558+ frame. render_widget ( Clear , modal_area) ;
559+
560+ let block = Block :: default ( )
561+ . borders ( Borders :: ALL )
562+ . border_type ( BorderType :: Rounded )
563+ . border_style ( Style :: default ( ) . fg ( Color :: Red ) )
564+ . title ( " Warning " ) ;
565+
566+ let inner = block. inner ( modal_area) ;
567+ frame. render_widget ( block, modal_area) ;
568+
569+ let layout = Layout :: default ( )
570+ . direction ( Direction :: Vertical )
571+ . constraints ( [ Constraint :: Min ( 1 ) , Constraint :: Length ( 3 ) ] )
572+ . split ( inner) ;
573+
574+ let text = vec ! [
575+ Line :: from( vec![ Span :: styled(
576+ " ⚠ Disable your last monitor?" ,
577+ Style :: default ( ) . fg( Color :: Red ) . add_modifier( Modifier :: BOLD ) ,
578+ ) ] ) ,
579+ Line :: from( vec![ Span :: styled(
580+ " No way to undo from here." ,
581+ Style :: default ( ) . fg( Color :: Yellow ) ,
582+ ) ] ) ,
583+ Line :: from( "" ) ,
584+ Line :: from( vec![ Span :: styled(
585+ " To recover, you'll need to:" ,
586+ Style :: default ( ) . fg( Color :: White ) ,
587+ ) ] ) ,
588+ Line :: from( vec![ Span :: styled(
589+ " 1. Reboot your machine" ,
590+ Style :: default ( ) . fg( Color :: DarkGray ) ,
591+ ) ] ) ,
592+ Line :: from( vec![ Span :: styled(
593+ " 2. Open a TTY session" ,
594+ Style :: default ( ) . fg( Color :: DarkGray ) ,
595+ ) ] ) ,
596+ Line :: from( vec![
597+ Span :: styled( " 3. Edit " , Style :: default ( ) . fg( Color :: DarkGray ) ) ,
598+ Span :: styled( config_path, Style :: default ( ) . fg( Color :: Cyan ) ) ,
599+ ] ) ,
600+ Line :: from( vec![ Span :: styled(
601+ " and remove the disable line" ,
602+ Style :: default ( ) . fg( Color :: DarkGray ) ,
603+ ) ] ) ,
604+ Line :: from( vec![ Span :: styled(
605+ " 4. Reboot and log into your compositor" ,
606+ Style :: default ( ) . fg( Color :: DarkGray ) ,
607+ ) ] ) ,
608+ ] ;
609+
610+ let buttons = vec ! [
611+ Line :: from( vec![
612+ Span :: styled( " ┌───────┐ " , Style :: default ( ) . fg( Color :: Red ) ) ,
613+ Span :: styled( "┌──────┐" , Style :: default ( ) . fg( Color :: Green ) ) ,
614+ ] ) ,
615+ Line :: from( vec![
616+ Span :: styled( " │ " , Style :: default ( ) . fg( Color :: Red ) ) ,
617+ Span :: styled(
618+ "[Y]" ,
619+ Style :: default ( ) . fg( Color :: Red ) . add_modifier( Modifier :: BOLD ) ,
620+ ) ,
621+ Span :: styled( "es " , Style :: default ( ) . fg( Color :: Red ) ) ,
622+ Span :: styled( "│ " , Style :: default ( ) . fg( Color :: Red ) ) ,
623+ Span :: styled( "│ " , Style :: default ( ) . fg( Color :: Green ) ) ,
624+ Span :: styled(
625+ "[N]" ,
626+ Style :: default ( )
627+ . fg( Color :: Green )
628+ . add_modifier( Modifier :: BOLD ) ,
629+ ) ,
630+ Span :: styled( "o " , Style :: default ( ) . fg( Color :: Green ) ) ,
631+ Span :: styled( "│" , Style :: default ( ) . fg( Color :: Green ) ) ,
632+ ] ) ,
633+ Line :: from( vec![
634+ Span :: styled( " └───────┘ " , Style :: default ( ) . fg( Color :: Red ) ) ,
635+ Span :: styled( "└──────┘" , Style :: default ( ) . fg( Color :: Green ) ) ,
636+ ] ) ,
637+ ] ;
638+
639+ let text_widget =
640+ Paragraph :: new ( text) . style ( Style :: default ( ) . fg ( Color :: White ) ) ;
641+ frame. render_widget ( text_widget, layout[ 0 ] ) ;
642+
643+ let buttons_widget =
644+ Paragraph :: new ( buttons) . style ( Style :: default ( ) . fg ( Color :: White ) ) ;
645+ frame. render_widget ( buttons_widget, layout[ 1 ] ) ;
646+ }
0 commit comments