@@ -404,90 +404,125 @@ pub(super) fn rebuild_container_metrics(list: >k::ListBox, detail: &ObjectDeta
404404pub ( super ) fn container_metric_row (
405405 resources : & ContainerResources ,
406406 usage : Option < & ContainerUsage > ,
407- ) -> adw:: ExpanderRow {
408- let action = adw:: ExpanderRow :: builder ( )
407+ ) -> adw:: ActionRow {
408+ let action = adw:: ActionRow :: builder ( )
409409 . title ( resources. name . as_str ( ) )
410- . expanded ( false )
410+ . subtitle ( if usage. is_some ( ) {
411+ tr ( "Current / Request / Limit" )
412+ } else {
413+ tr ( "Metrics unavailable; showing requests and limits" )
414+ } )
411415 . build ( ) ;
412- if let Some ( usage) = usage {
413- let metrics = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 12 ) ;
414- metrics. set_valign ( gtk:: Align :: Center ) ;
415- metrics. set_margin_start ( 12 ) ;
416- metrics. append ( & metric_badge (
417- "applications-engineering-symbolic" ,
418- & tr ( "CPU usage" ) ,
419- & format_cpu_quantity ( & usage. cpu ) ,
420- & usage. cpu ,
421- ) ) ;
422- metrics. append ( & metric_badge (
423- "drive-harddisk-symbolic" ,
424- & tr ( "Memory usage" ) ,
425- & format_memory_quantity ( & usage. memory ) ,
426- & usage. memory ,
427- ) ) ;
428- action. add_suffix ( & metrics) ;
429- } else {
430- action. set_subtitle ( & tr ( "Metrics unavailable" ) ) ;
431- }
432- action. add_row ( & container_resource_row (
416+
417+ let metrics = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 12 ) ;
418+ metrics. set_valign ( gtk:: Align :: Center ) ;
419+ metrics. set_margin_start ( 12 ) ;
420+ metrics. append ( & resource_usage_chip (
433421 & tr ( "CPU" ) ,
434422 usage. map ( |usage| usage. cpu . as_str ( ) ) ,
435423 & resources. cpu_request ,
436424 & resources. cpu_limit ,
437425 "applications-engineering-symbolic" ,
438426 format_cpu_quantity,
439427 ) ) ;
440- action . add_row ( & container_resource_row (
428+ metrics . append ( & resource_usage_chip (
441429 & tr ( "Memory" ) ,
442430 usage. map ( |usage| usage. memory . as_str ( ) ) ,
443431 & resources. memory_request ,
444432 & resources. memory_limit ,
445433 "drive-harddisk-symbolic" ,
446434 format_memory_quantity,
447435 ) ) ;
436+ action. add_suffix ( & metrics) ;
448437 action
449438}
450439
451- fn container_resource_row (
440+ fn resource_usage_chip (
452441 title : & str ,
453442 current : Option < & str > ,
454443 request : & str ,
455444 limit : & str ,
456445 icon_name : & str ,
457446 formatter : fn ( & str ) -> String ,
458- ) -> adw:: ActionRow {
459- let row = adw:: ActionRow :: builder ( ) . title ( title) . build ( ) ;
460- row. add_prefix ( & gtk:: Image :: from_icon_name ( available_icon_name (
447+ ) -> gtk:: Box {
448+ let chip = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 6 ) ;
449+ chip. set_valign ( gtk:: Align :: Center ) ;
450+ chip. set_size_request ( 150 , -1 ) ;
451+
452+ let icon = gtk:: Image :: from_icon_name ( available_icon_name (
461453 icon_name,
462454 "applications-system-symbolic" ,
463- ) ) ) ;
464- row. add_suffix ( & resource_text_pair (
465- & tr ( "Current" ) ,
466- current. unwrap_or ( "-" ) ,
467- formatter,
468455 ) ) ;
469- row. add_suffix ( & resource_text_pair ( & tr ( "Request" ) , request, formatter) ) ;
470- row. add_suffix ( & resource_text_pair ( & tr ( "Limit" ) , limit, formatter) ) ;
471- row
472- }
456+ icon. add_css_class ( "dim-label" ) ;
457+ icon. set_tooltip_text ( Some ( title) ) ;
458+ chip. append ( & icon) ;
459+
460+ let text = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 1 ) ;
461+ let heading = gtk:: Label :: new ( Some ( title) ) ;
462+ heading. add_css_class ( "caption" ) ;
463+ heading. add_css_class ( "dim-label" ) ;
464+ heading. set_xalign ( 0.0 ) ;
465+ text. append ( & heading) ;
466+
467+ let bar_row = gtk:: Box :: new ( gtk:: Orientation :: Horizontal , 6 ) ;
468+ bar_row. set_valign ( gtk:: Align :: Center ) ;
469+ let bar = gtk:: LevelBar :: new ( ) ;
470+ bar. set_size_request ( 76 , -1 ) ;
471+ bar. set_valign ( gtk:: Align :: Center ) ;
472+ bar. set_min_value ( 0.0 ) ;
473+ bar. set_max_value ( 1.0 ) ;
474+ bar. remove_offset_value ( Some ( "low" ) ) ;
475+ bar. remove_offset_value ( Some ( "high" ) ) ;
476+ bar. add_offset_value ( "lb-normal" , 0.85 ) ;
477+ bar. add_offset_value ( "lb-warning" , 0.95 ) ;
478+ bar. add_offset_value ( "lb-error" , 1.0 ) ;
479+
480+ let raw_current = current. unwrap_or ( "-" ) ;
481+ let base = super :: utils:: parse_quantity ( request)
482+ . filter ( |value| * value > 0.0 )
483+ . or_else ( || super :: utils:: parse_quantity ( limit) . filter ( |value| * value > 0.0 ) ) ;
484+ let current_value = super :: utils:: parse_quantity ( raw_current) ;
485+ let percent = current_value
486+ . zip ( base)
487+ . map ( |( current, base) | current / base) ;
488+ let formatted_current = format_resource_value ( raw_current, formatter) ;
489+ let formatted_request = format_resource_value ( request, formatter) ;
490+ let formatted_limit = format_resource_value ( limit, formatter) ;
491+
492+ if let Some ( percent) = percent {
493+ bar. set_value ( percent. clamp ( 0.0 , 1.0 ) ) ;
494+ } else {
495+ bar. set_value ( 0.0 ) ;
496+ }
473497
474- fn resource_text_pair ( label : & str , value : & str , formatter : fn ( & str ) -> String ) -> gtk:: Box {
475- let pair = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 2 ) ;
476- pair. set_valign ( gtk:: Align :: Center ) ;
477- pair. set_margin_start ( 10 ) ;
478-
479- let title = gtk:: Label :: new ( Some ( label) ) ;
480- title. add_css_class ( "caption" ) ;
481- title. add_css_class ( "dim-label" ) ;
482- title. set_xalign ( 1.0 ) ;
483- pair. append ( & title) ;
484-
485- let value_label = gtk:: Label :: new ( Some ( & format_resource_value ( value, formatter) ) ) ;
486- value_label. add_css_class ( "caption" ) ;
487- value_label. set_xalign ( 1.0 ) ;
488- value_label. set_tooltip_text ( Some ( value) ) ;
489- pair. append ( & value_label) ;
490- pair
498+ let tooltip = if let Some ( percent) = percent {
499+ tr_format (
500+ "{resource}: {percent}% used. Current {current}, Request {request}, Limit {limit}" ,
501+ & [
502+ ( "{resource}" , title. to_owned ( ) ) ,
503+ ( "{percent}" , format ! ( "{:.0}" , percent * 100.0 ) ) ,
504+ ( "{current}" , formatted_current. clone ( ) ) ,
505+ ( "{request}" , formatted_request) ,
506+ ( "{limit}" , formatted_limit) ,
507+ ] ,
508+ )
509+ } else {
510+ tr_format (
511+ "{resource}: Current {current}, Request {request}, Limit {limit}" ,
512+ & [
513+ ( "{resource}" , title. to_owned ( ) ) ,
514+ ( "{current}" , formatted_current. clone ( ) ) ,
515+ ( "{request}" , formatted_request) ,
516+ ( "{limit}" , formatted_limit) ,
517+ ] ,
518+ )
519+ } ;
520+ chip. set_tooltip_text ( Some ( & tooltip) ) ;
521+ bar. set_tooltip_text ( Some ( & tooltip) ) ;
522+ bar_row. append ( & bar) ;
523+ text. append ( & bar_row) ;
524+ chip. append ( & text) ;
525+ chip
491526}
492527
493528fn format_resource_value ( value : & str , formatter : fn ( & str ) -> String ) -> String {
0 commit comments