mirror of
https://github.com/danog/ytop.git
synced 2024-11-26 12:04:50 +01:00
Convert spaces to tabs
This commit is contained in:
parent
64c6594edf
commit
d3cd9a5e2e
8
.editorconfig
Normal file
8
.editorconfig
Normal file
@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
@ -0,0 +1 @@
|
||||
hard_tabs = true
|
26
.travis.yml
26
.travis.yml
@ -3,27 +3,27 @@ language: rust
|
||||
cache: cargo
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env: TARGET=x86_64-unknown-linux-gnu
|
||||
os: linux
|
||||
include:
|
||||
- env: TARGET=x86_64-unknown-linux-gnu
|
||||
os: linux
|
||||
|
||||
install: true
|
||||
script: ./ci/script.sh
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: $GITHUB_TOKEN
|
||||
file_glob: true
|
||||
file: "./*.tar.gz"
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
provider: releases
|
||||
api_key: $GITHUB_TOKEN
|
||||
file_glob: true
|
||||
file: "./*.tar.gz"
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
|
||||
if: tag IS present
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
email:
|
||||
on_success: never
|
||||
|
@ -3,9 +3,9 @@
|
||||
NAME=${TRAVIS_REPO_SLUG#*/}
|
||||
|
||||
function main {
|
||||
rustup target add $TARGET
|
||||
cargo build --target $TARGET --release
|
||||
tar -czf $NAME-$TRAVIS_TAG-$TARGET.tar.gz -C ./target/$TARGET/release/ $NAME
|
||||
rustup target add $TARGET
|
||||
cargo build --target $TARGET --release
|
||||
tar -czf $NAME-$TRAVIS_TAG-$TARGET.tar.gz -C ./target/$TARGET/release/ $NAME
|
||||
}
|
||||
|
||||
main
|
||||
|
98
src/args.rs
98
src/args.rs
@ -3,75 +3,75 @@ use std::str::FromStr;
|
||||
use structopt::StructOpt;
|
||||
|
||||
pub enum Colorscheme {
|
||||
Default,
|
||||
DefaultDark,
|
||||
Monokai,
|
||||
SolarizedDark,
|
||||
Vice,
|
||||
Custom(String),
|
||||
Default,
|
||||
DefaultDark,
|
||||
Monokai,
|
||||
SolarizedDark,
|
||||
Vice,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl FromStr for Colorscheme {
|
||||
type Err = std::io::Error;
|
||||
type Err = std::io::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"default" => Colorscheme::Default,
|
||||
"default-dark" => Colorscheme::DefaultDark,
|
||||
"monokai" => Colorscheme::Monokai,
|
||||
"solarized-dark" => Colorscheme::SolarizedDark,
|
||||
"vice" => Colorscheme::Vice,
|
||||
_ => Colorscheme::Custom(s.to_string()),
|
||||
})
|
||||
}
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"default" => Colorscheme::Default,
|
||||
"default-dark" => Colorscheme::DefaultDark,
|
||||
"monokai" => Colorscheme::Monokai,
|
||||
"solarized-dark" => Colorscheme::SolarizedDark,
|
||||
"vice" => Colorscheme::Vice,
|
||||
_ => Colorscheme::Custom(s.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub struct Args {
|
||||
/// Set a colorscheme.
|
||||
#[structopt(
|
||||
short = "c",
|
||||
long = "colorscheme",
|
||||
default_value = "default",
|
||||
long_help = r"Colorschemes:
|
||||
/// Set a colorscheme.
|
||||
#[structopt(
|
||||
short = "c",
|
||||
long = "colorscheme",
|
||||
default_value = "default",
|
||||
long_help = r"Colorschemes:
|
||||
- default
|
||||
- default-dark (for white backgrounds)
|
||||
- solarized-dark
|
||||
- monokai
|
||||
- vice
|
||||
"
|
||||
)]
|
||||
pub colorscheme: Colorscheme,
|
||||
)]
|
||||
pub colorscheme: Colorscheme,
|
||||
|
||||
/// Only show the CPU, Mem, and Process widgets.
|
||||
#[structopt(short = "m", long = "minimal")]
|
||||
pub minimal: bool,
|
||||
/// Only show the CPU, Mem, and Process widgets.
|
||||
#[structopt(short = "m", long = "minimal")]
|
||||
pub minimal: bool,
|
||||
|
||||
/// Number of times per second to update the CPU and Mem widgets.
|
||||
#[structopt(short = "r", long = "rate", default_value = "1")]
|
||||
pub rate: f64,
|
||||
/// Number of times per second to update the CPU and Mem widgets.
|
||||
#[structopt(short = "r", long = "rate", default_value = "1")]
|
||||
pub rate: f64,
|
||||
|
||||
/// Show each CPU in the CPU widget.
|
||||
#[structopt(short = "p", long = "per-cpu")]
|
||||
pub per_cpu: bool,
|
||||
/// Show each CPU in the CPU widget.
|
||||
#[structopt(short = "p", long = "per-cpu")]
|
||||
pub per_cpu: bool,
|
||||
|
||||
/// Show average CPU in the CPU widget.
|
||||
#[structopt(short = "a", long = "average-cpu")]
|
||||
pub average_cpu: bool,
|
||||
/// Show average CPU in the CPU widget.
|
||||
#[structopt(short = "a", long = "average-cpu")]
|
||||
pub average_cpu: bool,
|
||||
|
||||
/// Show temperatures in fahrenheit.
|
||||
#[structopt(short = "f", long = "fahrenheit")]
|
||||
pub fahrenheit: bool,
|
||||
/// Show temperatures in fahrenheit.
|
||||
#[structopt(short = "f", long = "fahrenheit")]
|
||||
pub fahrenheit: bool,
|
||||
|
||||
/// Show a statusbar with the time.
|
||||
#[structopt(short = "s", long = "statusbar")]
|
||||
pub statusbar: bool,
|
||||
/// Show a statusbar with the time.
|
||||
#[structopt(short = "s", long = "statusbar")]
|
||||
pub statusbar: bool,
|
||||
|
||||
/// Show Battery widget (overridden by 'minimal' flag).
|
||||
#[structopt(short = "b", long = "battery")]
|
||||
pub battery: bool,
|
||||
/// Show Battery widget (overridden by 'minimal' flag).
|
||||
#[structopt(short = "b", long = "battery")]
|
||||
pub battery: bool,
|
||||
|
||||
/// Comma separated list of network interfaces to show. Prepend an interface with '!' to hide it. 'all' shows all interfaces.
|
||||
#[structopt(short = "i", long = "interfaces", default_value = "!tun0")]
|
||||
pub interfaces: String,
|
||||
/// Comma separated list of network interfaces to show. Prepend an interface with '!' to hide it. 'all' shows all interfaces.
|
||||
#[structopt(short = "i", long = "interfaces", default_value = "!tun0")]
|
||||
pub interfaces: String,
|
||||
}
|
||||
|
@ -2,24 +2,24 @@ use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Colorscheme {
|
||||
fg: i64,
|
||||
bg: i64,
|
||||
fg: i64,
|
||||
bg: i64,
|
||||
|
||||
titles: i64,
|
||||
borders: i64,
|
||||
titles: i64,
|
||||
borders: i64,
|
||||
|
||||
battery_lines: Vec<i64>,
|
||||
battery_lines: Vec<i64>,
|
||||
|
||||
// need at least 8 entries
|
||||
cpu_lines: Vec<i64>,
|
||||
// need at least 8 entries
|
||||
cpu_lines: Vec<i64>,
|
||||
|
||||
mem_main: i64,
|
||||
mem_swap: i64,
|
||||
mem_main: i64,
|
||||
mem_swap: i64,
|
||||
|
||||
net_bars: i64,
|
||||
net_bars: i64,
|
||||
|
||||
proc_cursor: i64,
|
||||
proc_cursor: i64,
|
||||
|
||||
temp_low: i64,
|
||||
temp_high: i64,
|
||||
temp_low: i64,
|
||||
temp_high: i64,
|
||||
}
|
||||
|
452
src/main.rs
452
src/main.rs
@ -27,271 +27,271 @@ use args::Args;
|
||||
use widgets::*;
|
||||
|
||||
struct Widgets {
|
||||
battery_widget: Option<BatteryWidget>,
|
||||
cpu_widget: CpuWidget,
|
||||
disk_widget: Option<DiskWidget>,
|
||||
help_menu: HelpMenu,
|
||||
mem_widget: MemWidget,
|
||||
net_widget: Option<NetWidget>,
|
||||
proc_widget: ProcWidget,
|
||||
statusbar: Option<Statusbar>,
|
||||
temp_widget: Option<TempWidget>,
|
||||
battery_widget: Option<BatteryWidget>,
|
||||
cpu_widget: CpuWidget,
|
||||
disk_widget: Option<DiskWidget>,
|
||||
help_menu: HelpMenu,
|
||||
mem_widget: MemWidget,
|
||||
net_widget: Option<NetWidget>,
|
||||
proc_widget: ProcWidget,
|
||||
statusbar: Option<Statusbar>,
|
||||
temp_widget: Option<TempWidget>,
|
||||
}
|
||||
|
||||
fn setup_terminal() -> io::Result<Terminal<CrosstermBackend>> {
|
||||
let screen = AlternateScreen::to_alternate(true)?;
|
||||
let backend = CrosstermBackend::with_alternate_screen(screen)?;
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.hide_cursor()?;
|
||||
terminal.clear()?;
|
||||
Ok(terminal)
|
||||
let screen = AlternateScreen::to_alternate(true)?;
|
||||
let backend = CrosstermBackend::with_alternate_screen(screen)?;
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.hide_cursor()?;
|
||||
terminal.clear()?;
|
||||
Ok(terminal)
|
||||
}
|
||||
|
||||
fn setup_ui_events() -> Receiver<InputEvent> {
|
||||
let (ui_events_sender, ui_events_receiver) = unbounded();
|
||||
thread::spawn(move || {
|
||||
let _screen = crossterm::RawScreen::into_raw_mode().unwrap();
|
||||
let input = crossterm::input();
|
||||
input.enable_mouse_mode().unwrap();
|
||||
let mut reader = input.read_sync();
|
||||
loop {
|
||||
ui_events_sender.send(reader.next().unwrap()).unwrap();
|
||||
}
|
||||
});
|
||||
ui_events_receiver
|
||||
let (ui_events_sender, ui_events_receiver) = unbounded();
|
||||
thread::spawn(move || {
|
||||
let _screen = crossterm::RawScreen::into_raw_mode().unwrap();
|
||||
let input = crossterm::input();
|
||||
input.enable_mouse_mode().unwrap();
|
||||
let mut reader = input.read_sync();
|
||||
loop {
|
||||
ui_events_sender.send(reader.next().unwrap()).unwrap();
|
||||
}
|
||||
});
|
||||
ui_events_receiver
|
||||
}
|
||||
|
||||
fn setup_ctrl_c() -> Result<Receiver<()>, ctrlc::Error> {
|
||||
let (sender, receiver) = unbounded();
|
||||
ctrlc::set_handler(move || {
|
||||
sender.send(()).unwrap();
|
||||
})?;
|
||||
let (sender, receiver) = unbounded();
|
||||
ctrlc::set_handler(move || {
|
||||
sender.send(()).unwrap();
|
||||
})?;
|
||||
|
||||
Ok(receiver)
|
||||
Ok(receiver)
|
||||
}
|
||||
|
||||
fn setup_logfile(logfile_path: &Path) {
|
||||
fs::create_dir_all(logfile_path.parent().unwrap()).unwrap();
|
||||
let logfile = fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(logfile_path)
|
||||
.unwrap();
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}]: {}",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.chain(logfile)
|
||||
.apply()
|
||||
.unwrap();
|
||||
fs::create_dir_all(logfile_path.parent().unwrap()).unwrap();
|
||||
let logfile = fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(logfile_path)
|
||||
.unwrap();
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}]: {}",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.chain(logfile)
|
||||
.apply()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn read_colorscheme(
|
||||
config_folder: &Path,
|
||||
colorscheme: &args::Colorscheme,
|
||||
config_folder: &Path,
|
||||
colorscheme: &args::Colorscheme,
|
||||
) -> serde_json::Result<colorscheme::Colorscheme> {
|
||||
match colorscheme {
|
||||
args::Colorscheme::Custom(name) => serde_json::from_str(
|
||||
&fs::read_to_string(config_folder.join(name).with_extension("json")).unwrap(),
|
||||
),
|
||||
_ => {
|
||||
let json_string = match colorscheme {
|
||||
args::Colorscheme::Default => include_str!("../colorschemes/default.json"),
|
||||
args::Colorscheme::DefaultDark => include_str!("../colorschemes/default-dark.json"),
|
||||
args::Colorscheme::SolarizedDark => {
|
||||
include_str!("../colorschemes/solarized-dark.json")
|
||||
}
|
||||
args::Colorscheme::Monokai => include_str!("../colorschemes/monokai.json"),
|
||||
args::Colorscheme::Vice => include_str!("../colorschemes/vice.json"),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Ok(serde_json::from_str(json_string)
|
||||
.expect("statically defined and verified json colorschemes"))
|
||||
}
|
||||
}
|
||||
match colorscheme {
|
||||
args::Colorscheme::Custom(name) => serde_json::from_str(
|
||||
&fs::read_to_string(config_folder.join(name).with_extension("json")).unwrap(),
|
||||
),
|
||||
_ => {
|
||||
let json_string = match colorscheme {
|
||||
args::Colorscheme::Default => include_str!("../colorschemes/default.json"),
|
||||
args::Colorscheme::DefaultDark => include_str!("../colorschemes/default-dark.json"),
|
||||
args::Colorscheme::SolarizedDark => {
|
||||
include_str!("../colorschemes/solarized-dark.json")
|
||||
}
|
||||
args::Colorscheme::Monokai => include_str!("../colorschemes/monokai.json"),
|
||||
args::Colorscheme::Vice => include_str!("../colorschemes/vice.json"),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Ok(serde_json::from_str(json_string)
|
||||
.expect("statically defined and verified json colorschemes"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_widgets(args: &Args, colorscheme: &colorscheme::Colorscheme) -> Widgets {
|
||||
let battery_widget = Some(BatteryWidget::new());
|
||||
let cpu_widget = CpuWidget::new(Duration::from_secs(1), args.average_cpu, args.per_cpu);
|
||||
let disk_widget = Some(DiskWidget::new());
|
||||
let help_menu = HelpMenu::new();
|
||||
let mem_widget = MemWidget::new(Duration::from_secs(1));
|
||||
let net_widget = Some(NetWidget::new());
|
||||
let proc_widget = ProcWidget::new();
|
||||
let statusbar = Some(Statusbar::new());
|
||||
let temp_widget = Some(TempWidget::new());
|
||||
let battery_widget = Some(BatteryWidget::new());
|
||||
let cpu_widget = CpuWidget::new(Duration::from_secs(1), args.average_cpu, args.per_cpu);
|
||||
let disk_widget = Some(DiskWidget::new());
|
||||
let help_menu = HelpMenu::new();
|
||||
let mem_widget = MemWidget::new(Duration::from_secs(1));
|
||||
let net_widget = Some(NetWidget::new());
|
||||
let proc_widget = ProcWidget::new();
|
||||
let statusbar = Some(Statusbar::new());
|
||||
let temp_widget = Some(TempWidget::new());
|
||||
|
||||
Widgets {
|
||||
battery_widget,
|
||||
cpu_widget,
|
||||
disk_widget,
|
||||
help_menu,
|
||||
mem_widget,
|
||||
net_widget,
|
||||
proc_widget,
|
||||
statusbar,
|
||||
temp_widget,
|
||||
}
|
||||
Widgets {
|
||||
battery_widget,
|
||||
cpu_widget,
|
||||
disk_widget,
|
||||
help_menu,
|
||||
mem_widget,
|
||||
net_widget,
|
||||
proc_widget,
|
||||
statusbar,
|
||||
temp_widget,
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_widgets(widgets: &mut Widgets, ticks: i64) {
|
||||
let cpu = widgets.cpu_widget.update();
|
||||
let mem = widgets.mem_widget.update();
|
||||
let proc = widgets.proc_widget.update();
|
||||
if let (Some(disk_widget), Some(net_widget), Some(temp_widget)) = (
|
||||
widgets.disk_widget.as_mut(),
|
||||
widgets.net_widget.as_mut(),
|
||||
widgets.temp_widget.as_mut(),
|
||||
) {
|
||||
let disk = disk_widget.update();
|
||||
let net = net_widget.update();
|
||||
let temp = temp_widget.update();
|
||||
if let Some(battery_widget) = widgets.battery_widget.as_mut() {
|
||||
let battery = battery_widget.update();
|
||||
join!(cpu, mem, proc, disk, net, temp, battery);
|
||||
} else {
|
||||
join!(cpu, mem, proc, disk, net, temp);
|
||||
}
|
||||
} else {
|
||||
join!(cpu, mem, proc);
|
||||
}
|
||||
let cpu = widgets.cpu_widget.update();
|
||||
let mem = widgets.mem_widget.update();
|
||||
let proc = widgets.proc_widget.update();
|
||||
if let (Some(disk_widget), Some(net_widget), Some(temp_widget)) = (
|
||||
widgets.disk_widget.as_mut(),
|
||||
widgets.net_widget.as_mut(),
|
||||
widgets.temp_widget.as_mut(),
|
||||
) {
|
||||
let disk = disk_widget.update();
|
||||
let net = net_widget.update();
|
||||
let temp = temp_widget.update();
|
||||
if let Some(battery_widget) = widgets.battery_widget.as_mut() {
|
||||
let battery = battery_widget.update();
|
||||
join!(cpu, mem, proc, disk, net, temp, battery);
|
||||
} else {
|
||||
join!(cpu, mem, proc, disk, net, temp);
|
||||
}
|
||||
} else {
|
||||
join!(cpu, mem, proc);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_widgets<B: Backend>(terminal: &mut Terminal<B>, widgets: &mut Widgets) -> io::Result<()> {
|
||||
terminal.draw(|mut frame| {
|
||||
let vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Ratio(1, 3),
|
||||
Constraint::Ratio(1, 3),
|
||||
Constraint::Ratio(1, 3),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(frame.size());
|
||||
widgets.cpu_widget.render(&mut frame, vertical_chunks[0]);
|
||||
let middle_horizontal_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Ratio(1, 3), Constraint::Ratio(2, 3)].as_ref())
|
||||
.split(vertical_chunks[1]);
|
||||
widgets
|
||||
.mem_widget
|
||||
.render(&mut frame, middle_horizontal_chunks[1]);
|
||||
let middle_left_vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref())
|
||||
.split(middle_horizontal_chunks[0]);
|
||||
widgets
|
||||
.disk_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, middle_left_vertical_chunks[0]);
|
||||
widgets
|
||||
.temp_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, middle_left_vertical_chunks[1]);
|
||||
let bottom_horizontal_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref())
|
||||
.split(vertical_chunks[2]);
|
||||
widgets
|
||||
.net_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, bottom_horizontal_chunks[0]);
|
||||
widgets
|
||||
.proc_widget
|
||||
.render(&mut frame, bottom_horizontal_chunks[1]);
|
||||
})
|
||||
terminal.draw(|mut frame| {
|
||||
let vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Ratio(1, 3),
|
||||
Constraint::Ratio(1, 3),
|
||||
Constraint::Ratio(1, 3),
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(frame.size());
|
||||
widgets.cpu_widget.render(&mut frame, vertical_chunks[0]);
|
||||
let middle_horizontal_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Ratio(1, 3), Constraint::Ratio(2, 3)].as_ref())
|
||||
.split(vertical_chunks[1]);
|
||||
widgets
|
||||
.mem_widget
|
||||
.render(&mut frame, middle_horizontal_chunks[1]);
|
||||
let middle_left_vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref())
|
||||
.split(middle_horizontal_chunks[0]);
|
||||
widgets
|
||||
.disk_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, middle_left_vertical_chunks[0]);
|
||||
widgets
|
||||
.temp_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, middle_left_vertical_chunks[1]);
|
||||
let bottom_horizontal_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)].as_ref())
|
||||
.split(vertical_chunks[2]);
|
||||
widgets
|
||||
.net_widget
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(&mut frame, bottom_horizontal_chunks[0]);
|
||||
widgets
|
||||
.proc_widget
|
||||
.render(&mut frame, bottom_horizontal_chunks[1]);
|
||||
})
|
||||
}
|
||||
|
||||
fn draw_help_menu<B: Backend>(
|
||||
terminal: &mut Terminal<B>,
|
||||
help_menu: &mut HelpMenu,
|
||||
terminal: &mut Terminal<B>,
|
||||
help_menu: &mut HelpMenu,
|
||||
) -> io::Result<()> {
|
||||
terminal.draw(|mut frame| {})
|
||||
terminal.draw(|mut frame| {})
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let args = Args::from_args();
|
||||
let mut show_help_menu = false;
|
||||
let args = Args::from_args();
|
||||
let mut show_help_menu = false;
|
||||
|
||||
let program_name = env!("CARGO_PKG_NAME");
|
||||
let app_dirs = AppDirs::new(Some(program_name), AppUI::CommandLine).unwrap();
|
||||
let logfile_path = app_dirs.state_dir.join("errors.log");
|
||||
let program_name = env!("CARGO_PKG_NAME");
|
||||
let app_dirs = AppDirs::new(Some(program_name), AppUI::CommandLine).unwrap();
|
||||
let logfile_path = app_dirs.state_dir.join("errors.log");
|
||||
|
||||
let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap();
|
||||
let mut widgets = setup_widgets(&args, &colorscheme);
|
||||
let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap();
|
||||
let mut widgets = setup_widgets(&args, &colorscheme);
|
||||
|
||||
setup_logfile(&logfile_path);
|
||||
let mut terminal = setup_terminal().unwrap();
|
||||
setup_logfile(&logfile_path);
|
||||
let mut terminal = setup_terminal().unwrap();
|
||||
|
||||
let mut ticks = 0;
|
||||
let ticker = tick(Duration::from_secs(1));
|
||||
let ui_events_receiver = setup_ui_events();
|
||||
let ctrl_c_events = setup_ctrl_c().unwrap();
|
||||
let mut ticks = 0;
|
||||
let ticker = tick(Duration::from_secs(1));
|
||||
let ui_events_receiver = setup_ui_events();
|
||||
let ctrl_c_events = setup_ctrl_c().unwrap();
|
||||
|
||||
update_widgets(&mut widgets, ticks).await;
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
update_widgets(&mut widgets, ticks).await;
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
|
||||
loop {
|
||||
select! {
|
||||
recv(ctrl_c_events) -> _ => {
|
||||
break;
|
||||
}
|
||||
recv(ticker) -> _ => {
|
||||
ticks = (ticks + 1) % 60;
|
||||
update_widgets(&mut widgets, ticks).await;
|
||||
if !show_help_menu {
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
}
|
||||
recv(ui_events_receiver) -> message => {
|
||||
match message.unwrap() {
|
||||
InputEvent::Keyboard(key_event) => {
|
||||
match key_event {
|
||||
KeyEvent::Char(c) => match c {
|
||||
'q' => break,
|
||||
'?' => {
|
||||
show_help_menu = !show_help_menu;
|
||||
if show_help_menu {
|
||||
draw_help_menu(&mut terminal, &mut widgets.help_menu).unwrap();
|
||||
} else {
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
KeyEvent::Ctrl(c) => match c {
|
||||
'c' => break,
|
||||
_ => {},
|
||||
},
|
||||
KeyEvent::Esc => {
|
||||
if show_help_menu {
|
||||
show_help_menu = false;
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
InputEvent::Mouse(mouse_event) => match mouse_event {
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loop {
|
||||
select! {
|
||||
recv(ctrl_c_events) -> _ => {
|
||||
break;
|
||||
}
|
||||
recv(ticker) -> _ => {
|
||||
ticks = (ticks + 1) % 60;
|
||||
update_widgets(&mut widgets, ticks).await;
|
||||
if !show_help_menu {
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
}
|
||||
recv(ui_events_receiver) -> message => {
|
||||
match message.unwrap() {
|
||||
InputEvent::Keyboard(key_event) => {
|
||||
match key_event {
|
||||
KeyEvent::Char(c) => match c {
|
||||
'q' => break,
|
||||
'?' => {
|
||||
show_help_menu = !show_help_menu;
|
||||
if show_help_menu {
|
||||
draw_help_menu(&mut terminal, &mut widgets.help_menu).unwrap();
|
||||
} else {
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
KeyEvent::Ctrl(c) => match c {
|
||||
'c' => break,
|
||||
_ => {},
|
||||
},
|
||||
KeyEvent::Esc => {
|
||||
if show_help_menu {
|
||||
show_help_menu = false;
|
||||
draw_widgets(&mut terminal, &mut widgets).unwrap();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
InputEvent::Mouse(mouse_event) => match mouse_event {
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub fn convert_localized_string(s: &str) -> String {
|
||||
s.replace(',', ".")
|
||||
s.replace(',', ".")
|
||||
}
|
||||
|
||||
pub fn celsius_to_fahrenheit(c: i64) -> i64 {
|
||||
(c as f64 * (9f64 / 5f64)) as i64 + 32
|
||||
(c as f64 * (9f64 / 5f64)) as i64 + 32
|
||||
}
|
||||
|
@ -8,31 +8,31 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct BatteryWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
|
||||
battery_data: HashMap<String, Vec<(f64, f64)>>,
|
||||
battery_data: HashMap<String, Vec<(f64, f64)>>,
|
||||
}
|
||||
|
||||
impl BatteryWidget {
|
||||
pub fn new() -> BatteryWidget {
|
||||
BatteryWidget {
|
||||
title: " Batteries ".to_string(),
|
||||
update_interval: Duration::from_secs(60),
|
||||
update_count: 0.0,
|
||||
pub fn new() -> BatteryWidget {
|
||||
BatteryWidget {
|
||||
title: " Batteries ".to_string(),
|
||||
update_interval: Duration::from_secs(60),
|
||||
update_count: 0.0,
|
||||
|
||||
battery_data: HashMap::new(),
|
||||
}
|
||||
}
|
||||
battery_data: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for BatteryWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use tui::style::{Color, Style};
|
||||
use tui::widgets::{Block, Borders};
|
||||
|
||||
pub fn new() -> Block<'static> {
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_style(Style::default().fg(Color::Cyan))
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_style(Style::default().fg(Color::Cyan))
|
||||
}
|
||||
|
@ -8,98 +8,98 @@ use tui::widgets::{Axis, Chart, Dataset, Marker, Widget};
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct CpuWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
horizontal_scale: i64,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
horizontal_scale: i64,
|
||||
|
||||
cpu_count: usize,
|
||||
cpu_count: usize,
|
||||
|
||||
show_average_cpu: bool,
|
||||
show_per_cpu: bool,
|
||||
show_average_cpu: bool,
|
||||
show_per_cpu: bool,
|
||||
|
||||
average_cpu_data: (String, Vec<(f64, f64)>),
|
||||
per_cpu_data: Vec<(String, Vec<(f64, f64)>)>,
|
||||
average_cpu_data: (String, Vec<(f64, f64)>),
|
||||
per_cpu_data: Vec<(String, Vec<(f64, f64)>)>,
|
||||
}
|
||||
|
||||
impl CpuWidget {
|
||||
pub fn new(update_interval: Duration, show_average_cpu: bool, show_per_cpu: bool) -> CpuWidget {
|
||||
let mut cpu_widget = CpuWidget {
|
||||
title: " CPU Usage ".to_string(),
|
||||
update_interval,
|
||||
update_count: 0.0,
|
||||
horizontal_scale: 100,
|
||||
pub fn new(update_interval: Duration, show_average_cpu: bool, show_per_cpu: bool) -> CpuWidget {
|
||||
let mut cpu_widget = CpuWidget {
|
||||
title: " CPU Usage ".to_string(),
|
||||
update_interval,
|
||||
update_count: 0.0,
|
||||
horizontal_scale: 100,
|
||||
|
||||
cpu_count: num_cpus::get(),
|
||||
cpu_count: num_cpus::get(),
|
||||
|
||||
show_average_cpu,
|
||||
show_per_cpu,
|
||||
show_average_cpu,
|
||||
show_per_cpu,
|
||||
|
||||
average_cpu_data: ("AVRG".to_string(), Vec::new()),
|
||||
per_cpu_data: Vec::new(),
|
||||
};
|
||||
average_cpu_data: ("AVRG".to_string(), Vec::new()),
|
||||
per_cpu_data: Vec::new(),
|
||||
};
|
||||
|
||||
if !(show_average_cpu || show_per_cpu) {
|
||||
if cpu_widget.cpu_count <= 8 {
|
||||
cpu_widget.show_per_cpu = true
|
||||
} else {
|
||||
cpu_widget.show_average_cpu = true
|
||||
}
|
||||
}
|
||||
if !(show_average_cpu || show_per_cpu) {
|
||||
if cpu_widget.cpu_count <= 8 {
|
||||
cpu_widget.show_per_cpu = true
|
||||
} else {
|
||||
cpu_widget.show_average_cpu = true
|
||||
}
|
||||
}
|
||||
|
||||
if cpu_widget.show_per_cpu {
|
||||
for i in 0..cpu_widget.cpu_count {
|
||||
cpu_widget
|
||||
.per_cpu_data
|
||||
.push((format!("CPU{}", i), Vec::new()));
|
||||
}
|
||||
}
|
||||
if cpu_widget.show_per_cpu {
|
||||
for i in 0..cpu_widget.cpu_count {
|
||||
cpu_widget
|
||||
.per_cpu_data
|
||||
.push((format!("CPU{}", i), Vec::new()));
|
||||
}
|
||||
}
|
||||
|
||||
cpu_widget
|
||||
}
|
||||
cpu_widget
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
if self.show_average_cpu {
|
||||
self.average_cpu_data.1.push((self.update_count, 5.0));
|
||||
}
|
||||
if self.show_per_cpu {
|
||||
for i in 0..self.cpu_count {
|
||||
self.per_cpu_data[i].1.push((self.update_count, 5.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
if self.show_average_cpu {
|
||||
self.average_cpu_data.1.push((self.update_count, 5.0));
|
||||
}
|
||||
if self.show_per_cpu {
|
||||
for i in 0..self.cpu_count {
|
||||
self.per_cpu_data[i].1.push((self.update_count, 5.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for CpuWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
let mut datasets = Vec::new();
|
||||
if self.show_average_cpu {
|
||||
datasets.push(
|
||||
Dataset::default()
|
||||
.name(&self.average_cpu_data.0)
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&self.average_cpu_data.1),
|
||||
)
|
||||
}
|
||||
if self.show_per_cpu {
|
||||
for per_cpu_data in self.per_cpu_data.iter() {
|
||||
datasets.push(
|
||||
Dataset::default()
|
||||
.name(&per_cpu_data.0)
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&per_cpu_data.1),
|
||||
)
|
||||
}
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
let mut datasets = Vec::new();
|
||||
if self.show_average_cpu {
|
||||
datasets.push(
|
||||
Dataset::default()
|
||||
.name(&self.average_cpu_data.0)
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&self.average_cpu_data.1),
|
||||
)
|
||||
}
|
||||
if self.show_per_cpu {
|
||||
for per_cpu_data in self.per_cpu_data.iter() {
|
||||
datasets.push(
|
||||
Dataset::default()
|
||||
.name(&per_cpu_data.0)
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&per_cpu_data.1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Chart::<String, String>::default()
|
||||
.block(block::new().title(&self.title))
|
||||
.x_axis(Axis::default().bounds([self.update_count - 100.0, self.update_count + 1.0]))
|
||||
.y_axis(Axis::default().bounds([0.0, 100.0]))
|
||||
.datasets(&datasets)
|
||||
.draw(area, buf);
|
||||
}
|
||||
Chart::<String, String>::default()
|
||||
.block(block::new().title(&self.title))
|
||||
.x_axis(Axis::default().bounds([self.update_count - 100.0, self.update_count + 1.0]))
|
||||
.y_axis(Axis::default().bounds([0.0, 100.0]))
|
||||
.datasets(&datasets)
|
||||
.draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -9,38 +9,38 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
struct Partition {
|
||||
name: String,
|
||||
mountpoint: PathBuf,
|
||||
bytes_read: u64,
|
||||
bytes_written: u64,
|
||||
bytes_read_recently: u64,
|
||||
bytes_written_recently: u64,
|
||||
used_percent: f64,
|
||||
bytes_free: u64,
|
||||
name: String,
|
||||
mountpoint: PathBuf,
|
||||
bytes_read: u64,
|
||||
bytes_written: u64,
|
||||
bytes_read_recently: u64,
|
||||
bytes_written_recently: u64,
|
||||
used_percent: f64,
|
||||
bytes_free: u64,
|
||||
}
|
||||
|
||||
pub struct DiskWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
|
||||
partitions: HashMap<String, Partition>,
|
||||
partitions: HashMap<String, Partition>,
|
||||
}
|
||||
|
||||
impl DiskWidget {
|
||||
pub fn new() -> DiskWidget {
|
||||
DiskWidget {
|
||||
title: " Disk Usage ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
pub fn new() -> DiskWidget {
|
||||
DiskWidget {
|
||||
title: " Disk Usage ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
|
||||
partitions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
partitions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {}
|
||||
pub async fn update(&mut self) {}
|
||||
}
|
||||
|
||||
impl Widget for DiskWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ const TITLE: &str = " Help Menu ";
|
||||
pub struct HelpMenu {}
|
||||
|
||||
impl HelpMenu {
|
||||
pub fn new() -> HelpMenu {
|
||||
HelpMenu {}
|
||||
}
|
||||
pub fn new() -> HelpMenu {
|
||||
HelpMenu {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for HelpMenu {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(TITLE).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(TITLE).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -7,27 +7,27 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct MemWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
}
|
||||
|
||||
impl MemWidget {
|
||||
pub fn new(update_interval: Duration) -> MemWidget {
|
||||
MemWidget {
|
||||
title: " Memory Usage ".to_string(),
|
||||
update_interval,
|
||||
update_count: 0.0,
|
||||
}
|
||||
}
|
||||
pub fn new(update_interval: Duration) -> MemWidget {
|
||||
MemWidget {
|
||||
title: " Memory Usage ".to_string(),
|
||||
update_interval,
|
||||
update_count: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for MemWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -7,23 +7,23 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct NetWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
}
|
||||
|
||||
impl NetWidget {
|
||||
pub fn new() -> NetWidget {
|
||||
NetWidget {
|
||||
title: " Network Usage ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
pub fn new() -> NetWidget {
|
||||
NetWidget {
|
||||
title: " Network Usage ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {}
|
||||
pub async fn update(&mut self) {}
|
||||
}
|
||||
|
||||
impl Widget for NetWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -7,23 +7,23 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct ProcWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
}
|
||||
|
||||
impl ProcWidget {
|
||||
pub fn new() -> ProcWidget {
|
||||
ProcWidget {
|
||||
title: " Processes ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
pub fn new() -> ProcWidget {
|
||||
ProcWidget {
|
||||
title: " Processes ".to_string(),
|
||||
update_interval: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {}
|
||||
pub async fn update(&mut self) {}
|
||||
}
|
||||
|
||||
impl Widget for ProcWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ use crate::widgets::block;
|
||||
pub struct Statusbar {}
|
||||
|
||||
impl Statusbar {
|
||||
pub fn new() -> Statusbar {
|
||||
Statusbar {}
|
||||
}
|
||||
pub fn new() -> Statusbar {
|
||||
Statusbar {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Statusbar {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
@ -7,31 +7,31 @@ use tui::widgets::Widget;
|
||||
use crate::widgets::block;
|
||||
|
||||
pub struct TempWidget {
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
title: String,
|
||||
update_interval: Duration,
|
||||
update_count: f64,
|
||||
|
||||
temp_data: Vec<(String, Vec<(f64, f64)>)>,
|
||||
temp_data: Vec<(String, Vec<(f64, f64)>)>,
|
||||
}
|
||||
|
||||
impl TempWidget {
|
||||
pub fn new() -> TempWidget {
|
||||
TempWidget {
|
||||
title: " Temperatures ".to_string(),
|
||||
update_interval: Duration::from_secs(5),
|
||||
update_count: 0.0,
|
||||
pub fn new() -> TempWidget {
|
||||
TempWidget {
|
||||
title: " Temperatures ".to_string(),
|
||||
update_interval: Duration::from_secs(5),
|
||||
update_count: 0.0,
|
||||
|
||||
temp_data: Vec::new(),
|
||||
}
|
||||
}
|
||||
temp_data: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
pub async fn update(&mut self) {
|
||||
self.update_count += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for TempWidget {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
|
||||
block::new().title(&self.title).draw(area, buf);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user