@@ -20,7 +20,7 @@ use crate::{
2020impl Painter {
2121 /// Inspired by htop.
2222 pub fn draw_basic_cpu (
23- & self , f : & mut Frame < ' _ > , app_state : & mut App , draw_loc : Rect , widget_id : u64 ,
23+ & self , f : & mut Frame < ' _ > , app_state : & mut App , mut draw_loc : Rect , widget_id : u64 ,
2424 ) {
2525 // Skip the first element, it's the "all" element
2626 if app_state. converted_data . cpu_data . len ( ) > 1 {
@@ -45,6 +45,32 @@ impl Painter {
4545 ) ;
4646 }
4747
48+ let ( cpu_data, avg_data) =
49+ maybe_split_avg ( cpu_data, app_state. app_config_fields . dedicated_average_row ) ;
50+
51+ if let Some ( avg) = avg_data {
52+ let ( outer, inner, ratio, style) = self . cpu_info ( & avg) ;
53+ let [ cores_loc, mut avg_loc] =
54+ Layout :: vertical ( [ Constraint :: Min ( 0 ) , Constraint :: Length ( 1 ) ] ) . areas ( draw_loc) ;
55+
56+ // The cores section all have horizontal margin, so to line up with the cores we
57+ // need to add some margin ourselves.
58+ avg_loc. x += 1 ;
59+ avg_loc. width -= 2 ;
60+
61+ f. render_widget (
62+ PipeGauge :: default ( )
63+ . gauge_style ( style)
64+ . label_style ( style)
65+ . inner_label ( inner)
66+ . start_label ( outer)
67+ . ratio ( ratio) ,
68+ avg_loc,
69+ ) ;
70+
71+ draw_loc = cores_loc;
72+ }
73+
4874 if draw_loc. height > 0 {
4975 let remaining_height = usize:: from ( draw_loc. height ) ;
5076 const REQUIRED_COLUMNS : usize = 4 ;
@@ -56,27 +82,7 @@ impl Painter {
5682 . direction ( Direction :: Horizontal )
5783 . split ( draw_loc) ;
5884
59- let mut gauge_info = cpu_data. iter ( ) . map ( |cpu| match cpu {
60- CpuWidgetData :: All => unreachable ! ( ) ,
61- CpuWidgetData :: Entry {
62- data_type,
63- data : _,
64- last_entry,
65- } => {
66- let ( outer, style) = match data_type {
67- CpuDataType :: Avg => ( "AVG" . to_string ( ) , self . colours . avg_colour_style ) ,
68- CpuDataType :: Cpu ( index) => (
69- format ! ( "{index:<3}" , ) ,
70- self . colours . cpu_colour_styles
71- [ index % self . colours . cpu_colour_styles . len ( ) ] ,
72- ) ,
73- } ;
74- let inner = format ! ( "{:>3.0}%" , last_entry. round( ) ) ;
75- let ratio = last_entry / 100.0 ;
76-
77- ( outer, inner, ratio, style)
78- }
79- } ) ;
85+ let mut gauge_info = cpu_data. iter ( ) . map ( |cpu| self . cpu_info ( cpu) ) ;
8086
8187 // Very ugly way to sync the gauge limit across all gauges.
8288 let hide_parts = columns
@@ -138,4 +144,64 @@ impl Painter {
138144 }
139145 }
140146 }
147+
148+ fn cpu_info ( & self , cpu : & CpuWidgetData ) -> ( String , String , f64 , tui:: style:: Style ) {
149+ let CpuWidgetData :: Entry {
150+ data_type,
151+ last_entry,
152+ ..
153+ } = cpu
154+ else {
155+ unreachable ! ( )
156+ } ;
157+
158+ let ( outer, style) = match data_type {
159+ CpuDataType :: Avg => ( "AVG" . to_string ( ) , self . colours . avg_colour_style ) ,
160+ CpuDataType :: Cpu ( index) => (
161+ format ! ( "{index:<3}" , ) ,
162+ self . colours . cpu_colour_styles [ index % self . colours . cpu_colour_styles . len ( ) ] ,
163+ ) ,
164+ } ;
165+ let inner = format ! ( "{:>3.0}%" , last_entry. round( ) ) ;
166+ let ratio = last_entry / 100.0 ;
167+
168+ ( outer, inner, ratio, style)
169+ }
170+ }
171+
172+ fn maybe_split_avg (
173+ data : & [ CpuWidgetData ] , separate_avg : bool ,
174+ ) -> ( Vec < CpuWidgetData > , Option < CpuWidgetData > ) {
175+ let mut cpu_data = vec ! [ ] ;
176+ let mut avg_data = None ;
177+
178+ for cpu in data {
179+ let CpuWidgetData :: Entry {
180+ data_type,
181+ data,
182+ last_entry,
183+ } = cpu
184+ else {
185+ unreachable ! ( )
186+ } ;
187+
188+ match data_type {
189+ CpuDataType :: Avg if separate_avg => {
190+ avg_data = Some ( CpuWidgetData :: Entry {
191+ data_type : * data_type,
192+ data : data. clone ( ) ,
193+ last_entry : * last_entry,
194+ } ) ;
195+ }
196+ _ => {
197+ cpu_data. push ( CpuWidgetData :: Entry {
198+ data_type : * data_type,
199+ data : data. clone ( ) ,
200+ last_entry : * last_entry,
201+ } ) ;
202+ }
203+ }
204+ }
205+
206+ ( cpu_data, avg_data)
141207}
0 commit comments