diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c04c5840..1b1ca4378 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#418](https://github.com/ClementTsang/bottom/pull/418): Removed automatically jumping to the top of the list for process sort shortcuts. The standard behaviour is to now stay in place. +- [#420](https://github.com/ClementTsang/bottom/pull/420): Updated tui-rs, allowing for prettier looking tables! + ## Bug Fixes - [#416](https://github.com/ClementTsang/bottom/pull/416): Fixes grouped vs ungrouped modes in the processes widget having inconsistent spacing. diff --git a/Cargo.lock b/Cargo.lock index 1231c7d7a..0142d3bc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "addr2line" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" dependencies = [ "gimli", ] @@ -35,16 +35,17 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.35" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "assert_cmd" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc1679af9a1ab4bea16f228b05d18f8363f8327b1fa8db00d2760cfafc6b61e" +checksum = "f2475b58cd94eb4f70159f4fd8844ba3b807532fe3131b3373fae060bbe30396" dependencies = [ + "bstr", "doc-comment", "predicates", "predicates-core", @@ -176,9 +177,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" dependencies = [ "addr2line", "cfg-if 1.0.0", @@ -269,6 +270,23 @@ dependencies = [ "winapi", ] +[[package]] +name = "bstr" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + +[[package]] +name = "byteorder" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" + [[package]] name = "cache-padded" version = "1.1.1" @@ -541,9 +559,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150" dependencies = [ "futures-channel", "futures-core", @@ -556,9 +574,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" +checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846" dependencies = [ "futures-core", "futures-sink", @@ -566,15 +584,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" +checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65" [[package]] name = "futures-executor" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65" +checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9" dependencies = [ "futures-core", "futures-task", @@ -583,9 +601,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" +checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500" [[package]] name = "futures-lite" @@ -598,15 +616,15 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite", + "pin-project-lite 0.1.11", "waker-fn", ] [[package]] name = "futures-macro" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" +checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -616,15 +634,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" +checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6" [[package]] name = "futures-task" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" +checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86" dependencies = [ "once_cell", ] @@ -637,9 +655,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.8" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" +checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b" dependencies = [ "futures-channel", "futures-core", @@ -648,7 +666,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project", + "pin-project-lite 0.2.4", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -837,9 +855,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" dependencies = [ "either", ] @@ -858,9 +876,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.81" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" [[package]] name = "lock_api" @@ -873,11 +891,11 @@ dependencies = [ [[package]] name = "log" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] @@ -1034,9 +1052,9 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" [[package]] name = "once_cell" @@ -1076,30 +1094,16 @@ dependencies = [ ] [[package]] -name = "pin-project" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.2" +name = "pin-project-lite" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" [[package]] name = "pin-project-lite" -version = "0.1.11" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" +checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" [[package]] name = "pin-utils" @@ -1122,9 +1126,9 @@ dependencies = [ [[package]] name = "predicates" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73dd9b7b200044694dfede9edf907c1ca19630908443e9447e624993700c6932" +checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa" dependencies = [ "difference", "float-cmp", @@ -1222,9 +1226,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" dependencies = [ "aho-corasick", "memchr", @@ -1232,11 +1236,20 @@ dependencies = [ "thread_local", ] +[[package]] +name = "regex-automata" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", +] + [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rustc-demangle" @@ -1252,18 +1265,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" dependencies = [ "proc-macro2", "quote", @@ -1340,9 +1353,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.54" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", @@ -1351,11 +1364,12 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.15.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67330cbee3b2a819e3365a773f05e884a136603687f812bf24db5b6c3d76b696" +checksum = "6c280c91abd1aed2e36be1bc8f56fbc7a2acbb2b58fbcac9641510179cc72dd9" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", + "core-foundation-sys 0.8.2", "doc-comment", "libc", "ntapi", @@ -1375,18 +1389,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote", @@ -1415,9 +1429,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] @@ -1430,9 +1444,9 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "tui" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4e6c82bb967df89f20b875fa8835fab5d5622c6a5efa574a1f0b6d0aa6e8f6" +checksum = "9ced152a8e9295a5b168adc254074525c17ac4a83c90b2716274cc38118bddc9" dependencies = [ "bitflags", "cassowary", @@ -1443,9 +1457,9 @@ dependencies = [ [[package]] name = "typed-builder" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ec6661b8cd8dc76d17f15f1cf1da27fc3dd58850ccc220d04653b48e0fae3ba" +checksum = "345426c7406aa355b60c5007c79a2d1f5b605540072795222f17f6443e6a9c6f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index bfb6b1331..7e944d234 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,8 @@ codegen-units = 1 default = ["fern", "log"] [dependencies] -anyhow = "1.0.35" -backtrace = "~0.3" +anyhow = "1.0.38" +backtrace = "0.3.56" battery = "0.7.8" beef = "0.5.0" chrono = "0.4.19" @@ -39,26 +39,26 @@ ctrlc = { version = "3.1", features = ["termination"] } clap = "2.33" dirs-next = "2.0.0" fnv = "1.0.7" -futures = "0.3.8" +futures = "0.3.12" indexmap = "~1.6" -itertools = "0.9.0" +itertools = "0.10.0" once_cell = "1.5.2" -regex = "1.4.2" -serde = { version = "~1.0", features = ["derive"] } -sysinfo = "0.15.3" -thiserror = "1.0.22" -toml = "0.5.7" -tui = { version = "0.13.0", features = ["crossterm"], default-features = false } -typed-builder = "0.8.0" +regex = "1.4.3" +serde = { version = "1.0.123", features = ["derive"] } +sysinfo = "0.16.4" +thiserror = "1.0.24" +toml = "0.5.8" +tui = { version = "0.14.0", features = ["crossterm"], default-features = false } +typed-builder = "0.9.0" unicode-segmentation = "1.7.1" unicode-width = "0.1" # For debugging only... disable on release builds with --no-default-target for no? TODO: Redo this. fern = { version = "0.6.0", optional=true } -log = { version = "0.4.11", optional=true } +log = { version = "0.4.14", optional=true } [target.'cfg(unix)'.dependencies] -libc = "~0.2" +libc = "0.2.86" [target.'cfg(target_os = "linux")'.dependencies] heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory", "net", "sensors"] } @@ -72,8 +72,8 @@ heim = { version = "0.1.0-rc.1", features = ["disk", "memory"] } winapi = "0.3.9" [dev-dependencies] -assert_cmd = "1.0.2" -predicates = "1.0.6" +assert_cmd = "1.0.3" +predicates = "1.0.7" [build-dependencies] clap = "2.33" diff --git a/src/app.rs b/src/app.rs index ba06a28ae..8be7394d6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2757,7 +2757,7 @@ impl App { /// Moves the mouse to the widget that was clicked on, then propagates the click down to be /// handled by the widget specifically. - pub fn left_mouse_click_movement(&mut self, x: u16, y: u16) { + pub fn on_left_mouse_up(&mut self, x: u16, y: u16) { // Pretty dead simple - iterate through the widget map and go to the widget where the click // is within. @@ -2769,6 +2769,7 @@ impl App { // Short circuit if we're in basic table... we might have to handle the basic table arrow // case here... + if let Some(bt) = &mut self.basic_table_widget_state { if let ( Some((left_tlc_x, left_tlc_y)), diff --git a/src/canvas/widgets/battery_display.rs b/src/canvas/widgets/battery_display.rs index 8672ea1fb..89b55bfd7 100644 --- a/src/canvas/widgets/battery_display.rs +++ b/src/canvas/widgets/battery_display.rs @@ -129,40 +129,36 @@ impl BatteryDisplayWidget for Painter { charge_percentage, ); - let battery_items = vec![ - ["Charge %", &bars], - ["Consumption", &battery_details.watt_consumption], + let battery_items: Vec> = vec![ + vec!["Charge %", &bars], + vec!["Consumption", &battery_details.watt_consumption], if let Some(duration_until_full) = &battery_details.duration_until_full { - ["Time to full", duration_until_full] + vec!["Time to full", duration_until_full] } else if let Some(duration_until_empty) = &battery_details.duration_until_empty { - ["Time to empty", duration_until_empty] + vec!["Time to empty", duration_until_empty] } else { - ["Time to full/empty", "N/A"] + vec!["Time to full/empty", "N/A"] }, - ["Health %", &battery_details.health], + vec!["Health %", &battery_details.health], ]; - let battery_rows = battery_items.iter().map(|item| { - Row::StyledData( - item.iter(), - if charge_percentage < 10.0 { - self.colours.low_battery_colour - } else if charge_percentage < 50.0 { - self.colours.medium_battery_colour - } else { - self.colours.high_battery_colour - }, - ) + let battery_rows = battery_items.into_iter().map(|item| { + Row::new(item).style(if charge_percentage < 10.0 { + self.colours.low_battery_colour + } else if charge_percentage < 50.0 { + self.colours.medium_battery_colour + } else { + self.colours.high_battery_colour + }) }); // Draw f.render_widget( - Table::new([""].iter(), battery_rows) + Table::new(battery_rows) .block(battery_block) - .header_style(self.colours.table_header_style) - .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]) - .header_gap(table_gap), + .header(Row::new(vec![""]).bottom_margin(table_gap)) + .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]), margined_draw_loc, ); } else { diff --git a/src/canvas/widgets/cpu_graph.rs b/src/canvas/widgets/cpu_graph.rs index 299fe0323..e19da20aa 100644 --- a/src/canvas/widgets/cpu_graph.rs +++ b/src/canvas/widgets/cpu_graph.rs @@ -1,5 +1,4 @@ use once_cell::sync::Lazy; -use std::borrow::Cow; use unicode_segmentation::UnicodeSegmentation; use crate::{ @@ -18,7 +17,7 @@ use tui::{ symbols::Marker, terminal::Frame, text::Span, - text::Spans, + text::{Spans, Text}, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -314,7 +313,7 @@ impl CpuGraphWidget for Painter { let sliced_cpu_data = &cpu_data[start_position..]; - let mut offset_scroll_index = cpu_widget_state + let offset_scroll_index = cpu_widget_state .scroll_state .current_scroll_position .saturating_sub(start_position); @@ -343,58 +342,59 @@ impl CpuGraphWidget for Painter { let dcw = &cpu_widget_state.table_width_state.desired_column_widths; let ccw = &cpu_widget_state.table_width_state.calculated_column_widths; - let cpu_rows = sliced_cpu_data.iter().enumerate().filter_map(|(itx, cpu)| { - let truncated_name: Cow<'_, str> = + let cpu_rows = sliced_cpu_data.iter().enumerate().map(|(itx, cpu)| { + let mut truncated_name = if let (Some(desired_column_width), Some(calculated_column_width)) = (dcw.get(0), ccw.get(0)) { if *desired_column_width > *calculated_column_width { - Cow::Borrowed(&cpu.short_cpu_name) + Text::raw(&cpu.short_cpu_name) } else { - Cow::Borrowed(&cpu.cpu_name) + Text::raw(&cpu.cpu_name) } } else { - Cow::Borrowed(&cpu.cpu_name) - }; - let truncated_legend: Cow<'_, str> = - if let Some(calculated_column_width) = ccw.get(0) { - if *calculated_column_width == 0 && cpu.legend_value.is_empty() { - Cow::Borrowed("All") - } else { - Cow::Borrowed(&cpu.legend_value) - } - } else { - Cow::Borrowed(&cpu.legend_value) + Text::raw(&cpu.cpu_name) }; - let cpu_string_row: Vec> = vec![truncated_name, truncated_legend]; + let is_first_column_hidden = if let Some(calculated_column_width) = ccw.get(0) { + *calculated_column_width == 0 + } else { + false + }; - if cpu_string_row.is_empty() { - offset_scroll_index += 1; - None + let truncated_legend = if is_first_column_hidden && cpu.legend_value.is_empty() { + // For the case where we only have room for one column, display "All" in the normally blank area. + Text::raw("All") } else { - Some(Row::StyledData( - cpu_string_row.into_iter(), - if itx == offset_scroll_index { - self.colours.currently_selected_text_style - } else if itx + start_position == ALL_POSITION { - self.colours.all_colour_style - } else if show_avg_cpu { - if itx + start_position == AVG_POSITION { - self.colours.avg_colour_style - } else { - self.colours.cpu_colour_styles[(itx + start_position - - AVG_POSITION - - 1) - % self.colours.cpu_colour_styles.len()] - } + Text::raw(&cpu.legend_value) + }; + + if !is_first_column_hidden + && itx == offset_scroll_index + && itx + start_position == ALL_POSITION + { + truncated_name.patch_style(self.colours.currently_selected_text_style); + Row::new(vec![truncated_name, truncated_legend]) + } else { + let cpu_string_row = vec![truncated_name, truncated_legend]; + + Row::new(cpu_string_row).style(if itx == offset_scroll_index { + self.colours.currently_selected_text_style + } else if itx + start_position == ALL_POSITION { + self.colours.all_colour_style + } else if show_avg_cpu { + if itx + start_position == AVG_POSITION { + self.colours.avg_colour_style } else { self.colours.cpu_colour_styles[(itx + start_position - - ALL_POSITION + - AVG_POSITION - 1) % self.colours.cpu_colour_styles.len()] - }, - )) + } + } else { + self.colours.cpu_colour_styles[(itx + start_position - ALL_POSITION - 1) + % self.colours.cpu_colour_styles.len()] + }) } }); @@ -407,14 +407,17 @@ impl CpuGraphWidget for Painter { // Draw f.render_stateful_widget( - Table::new(CPU_LEGEND_HEADER.iter(), cpu_rows) + Table::new(cpu_rows) .block( Block::default() .borders(Borders::ALL) .border_style(border_and_title_style), ) - .header_style(self.colours.table_header_style) - .highlight_style(self.colours.currently_selected_text_style) + .header( + Row::new(CPU_LEGEND_HEADER.to_vec()) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .widths( &(cpu_widget_state .table_width_state @@ -422,8 +425,7 @@ impl CpuGraphWidget for Painter { .iter() .map(|calculated_width| Constraint::Length(*calculated_width as u16)) .collect::>()), - ) - .header_gap(table_gap), + ), draw_loc, cpu_table_state, ); diff --git a/src/canvas/widgets/disk_table.rs b/src/canvas/widgets/disk_table.rs index 14cb4f60d..7d493f17c 100644 --- a/src/canvas/widgets/disk_table.rs +++ b/src/canvas/widgets/disk_table.rs @@ -4,7 +4,7 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, text::Span, - text::Spans, + text::{Spans, Text}, widgets::{Block, Borders, Row, Table}, }; @@ -16,7 +16,6 @@ use crate::{ }, constants::*, }; -use std::borrow::Cow; use unicode_segmentation::UnicodeSegmentation; const DISK_HEADERS: [&str; 7] = ["Disk", "Mount", "Used", "Free", "Total", "R/s", "W/s"]; @@ -140,17 +139,17 @@ impl DiskTableWidget for Painter { let first_n = graphemes [..(*calculated_col_width as usize - 1)] .concat(); - return Cow::Owned(format!("{}…", first_n)); + return Text::raw(format!("{}…", first_n)); } } } } - Cow::Borrowed(entry) + Text::raw(entry) }, ); - Row::Data(truncated_data) + Row::new(truncated_data) }); let (border_style, highlight_style) = if is_on_widget { @@ -241,9 +240,13 @@ impl DiskTableWidget for Painter { // Draw! f.render_stateful_widget( - Table::new(DISK_HEADERS.iter(), disk_rows) + Table::new(disk_rows) .block(disk_block) - .header_style(self.colours.table_header_style) + .header( + Row::new(DISK_HEADERS.to_vec()) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .highlight_style(highlight_style) .style(self.colours.text_style) .widths( @@ -253,8 +256,7 @@ impl DiskTableWidget for Painter { .iter() .map(|calculated_width| Constraint::Length(*calculated_width as u16)) .collect::>()), - ) - .header_gap(table_gap), + ), margined_draw_loc, disk_table_state, ); diff --git a/src/canvas/widgets/network_graph.rs b/src/canvas/widgets/network_graph.rs index ce9d1ce75..b6ee080b7 100644 --- a/src/canvas/widgets/network_graph.rs +++ b/src/canvas/widgets/network_graph.rs @@ -15,7 +15,7 @@ use tui::{ symbols::Marker, terminal::Frame, text::Span, - text::Spans, + text::{Spans, Text}, widgets::{Axis, Block, Borders, Chart, Dataset, Row, Table}, }; @@ -355,6 +355,12 @@ impl NetworkGraphWidget for Painter { fn draw_network_labels( &self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64, ) { + let table_gap = if draw_loc.height < TABLE_GAP_HEIGHT_LIMIT { + 0 + } else { + app_state.app_config_fields.table_gap + }; + let rx_display = &app_state.canvas_data.rx_display; let tx_display = &app_state.canvas_data.tx_display; let total_rx_display = &app_state.canvas_data.total_rx_display; @@ -362,14 +368,14 @@ impl NetworkGraphWidget for Painter { // Gross but I need it to work... let total_network = vec![vec![ - rx_display, - tx_display, - total_rx_display, - total_tx_display, + Text::raw(rx_display), + Text::raw(tx_display), + Text::raw(total_rx_display), + Text::raw(total_tx_display), ]]; let mapped_network = total_network - .iter() - .map(|val| Row::StyledData(val.iter(), self.colours.text_style)); + .into_iter() + .map(|val| Row::new(val).style(self.colours.text_style)); // Calculate widths let intrinsic_widths = get_column_widths( @@ -389,7 +395,12 @@ impl NetworkGraphWidget for Painter { // Draw f.render_widget( - Table::new(NETWORK_HEADERS.iter(), mapped_network) + Table::new(mapped_network) + .header( + Row::new(NETWORK_HEADERS.to_vec()) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .block(Block::default().borders(Borders::ALL).border_style( if app_state.current_widget.widget_id == widget_id { self.colours.highlighted_border_style @@ -397,7 +408,6 @@ impl NetworkGraphWidget for Painter { self.colours.border_style }, )) - .header_style(self.colours.table_header_style) .style(self.colours.text_style) .widths( &(intrinsic_widths diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs index f655b2c1f..316e71aeb 100644 --- a/src/canvas/widgets/process_table.rs +++ b/src/canvas/widgets/process_table.rs @@ -11,11 +11,10 @@ use tui::{ backend::Backend, layout::{Alignment, Constraint, Direction, Layout, Rect}, terminal::Frame, - text::{Span, Spans}, + text::{Span, Spans, Text}, widgets::{Block, Borders, Paragraph, Row, Table}, }; -use std::borrow::Cow; use unicode_segmentation::{GraphemeIndices, UnicodeSegmentation}; use unicode_width::UnicodeWidthStr; @@ -453,7 +452,7 @@ impl ProcessTableWidget for Painter { .collect::>(); if let Some(alternative) = alternative { - Cow::Borrowed(alternative) + Text::raw(alternative) } else if graphemes.len() > *calculated_col_width as usize && *calculated_col_width > 1 { @@ -461,33 +460,37 @@ impl ProcessTableWidget for Painter { let first_n = graphemes [..(*calculated_col_width as usize - 1)] .concat(); - Cow::Owned(format!("{}…", first_n)) + Text::raw(format!("{}…", first_n)) } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } }, ); if *disabled { - Row::StyledData(truncated_data, self.colours.disabled_text_style) + Row::new(truncated_data).style(self.colours.disabled_text_style) } else { - Row::Data(truncated_data) + Row::new(truncated_data) } }); f.render_stateful_widget( - Table::new(process_headers.iter(), process_rows) + Table::new(process_rows) + .header( + Row::new(process_headers) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .block(process_block) - .header_style(self.colours.table_header_style) .highlight_style(highlight_style) .style(self.colours.text_style) .widths( @@ -499,8 +502,7 @@ impl ProcessTableWidget for Painter { Constraint::Length(*calculated_width as u16) }) .collect::>()), - ) - .header_gap(table_gap), + ), margined_draw_loc, proc_table_state, ); @@ -826,7 +828,7 @@ impl ProcessTableWidget for Painter { let sort_options = sliced_vec .iter() - .map(|column| Row::Data(vec![column].into_iter())); + .map(|column| Row::new(vec![column.as_str()])); let column_state = &mut proc_widget_state.columns.column_state; column_state.select(Some( @@ -872,13 +874,16 @@ impl ProcessTableWidget for Painter { .split(draw_loc)[0]; f.render_stateful_widget( - Table::new(["Sort By"].iter(), sort_options) + Table::new(sort_options) + .header( + Row::new(vec!["Sort By"]) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .block(process_sort_block) .highlight_style(highlight_style) .style(self.colours.text_style) - .header_style(self.colours.table_header_style) - .widths(&[Constraint::Percentage(100)]) - .header_gap(table_gap), + .widths(&[Constraint::Percentage(100)]), margined_draw_loc, column_state, ); diff --git a/src/canvas/widgets/temp_table.rs b/src/canvas/widgets/temp_table.rs index f4e6a9c1c..5347fb9d6 100644 --- a/src/canvas/widgets/temp_table.rs +++ b/src/canvas/widgets/temp_table.rs @@ -4,7 +4,7 @@ use tui::{ layout::{Constraint, Direction, Layout, Rect}, terminal::Frame, text::Span, - text::Spans, + text::{Spans, Text}, widgets::{Block, Borders, Row, Table}, }; @@ -16,7 +16,6 @@ use crate::{ }, constants::*, }; -use std::borrow::Cow; use unicode_segmentation::UnicodeSegmentation; const TEMP_HEADERS: [&str; 2] = ["Sensor", "Temp"]; @@ -123,23 +122,23 @@ impl TempTableWidget for Painter { let first_n = graphemes [..(*calculated_col_width as usize - 1)] .concat(); - Cow::Owned(format!("{}…", first_n)) + Text::raw(format!("{}…", first_n)) } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } } else { - Cow::Borrowed(entry) + Text::raw(entry) } }, ); - Row::Data(truncated_data) + Row::new(truncated_data) }); let (border_style, highlight_style) = if is_on_widget { @@ -230,9 +229,13 @@ impl TempTableWidget for Painter { // Draw f.render_stateful_widget( - Table::new(TEMP_HEADERS.iter(), temperature_rows) + Table::new(temperature_rows) + .header( + Row::new(TEMP_HEADERS.to_vec()) + .style(self.colours.table_header_style) + .bottom_margin(table_gap), + ) .block(temp_block) - .header_style(self.colours.table_header_style) .highlight_style(highlight_style) .style(self.colours.text_style) .widths( @@ -242,8 +245,7 @@ impl TempTableWidget for Painter { .iter() .map(|calculated_width| Constraint::Length(*calculated_width as u16)) .collect::>()), - ) - .header_gap(table_gap), + ), margined_draw_loc, temp_table_state, ); diff --git a/src/lib.rs b/src/lib.rs index 7b15d37fa..f5e73a272 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,13 +75,11 @@ pub fn handle_mouse_event(event: MouseEvent, app: &mut App) { MouseEvent::ScrollUp(_x, _y, _modifiers) => app.handle_scroll_up(), MouseEvent::ScrollDown(_x, _y, _modifiers) => app.handle_scroll_down(), MouseEvent::Down(button, x, y, _modifiers) => { - // debug!("Button down: {:?}, x: {}, y: {}", button, x, y); - if !app.app_config_fields.disable_click { match button { crossterm::event::MouseButton::Left => { // Trigger left click widget activity - app.left_mouse_click_movement(x, y); + app.on_left_mouse_up(x, y); } crossterm::event::MouseButton::Right => {} _ => {}