Bevy+Ratutui powered Monitoring of Pico-Strike devices

View code reordering and initial styles

+82 -52
+9 -52
src/lib.rs
··· 2 2 mod messages; 3 3 mod net; 4 4 mod state; 5 + mod views; 5 6 6 7 use bevy::{ 7 - app::{AppExit, Plugin, PostUpdate, PreUpdate, Update}, 8 + app::{AppExit, Plugin, PreUpdate, Update}, 8 9 ecs::{ 9 - error::Result, 10 10 message::{MessageReader, MessageWriter}, 11 - name::Name, 12 - query::With, 13 - schedule::IntoScheduleConfigs, 14 - system::{Query, Res, ResMut}, 11 + system::{Res, ResMut}, 15 12 }, 16 - state::{app::AppExtStates, condition::in_state}, 13 + state::app::AppExtStates, 17 14 time::{Real, Time, Timer}, 18 15 }; 19 - use bevy_ratatui::{RatatuiContext, event::KeyMessage}; 20 - use ratatui::{ 21 - layout::{Constraint, HorizontalAlignment, Layout}, 22 - widgets::{Block, List, ListDirection, ListItem, Padding, Paragraph}, 23 - }; 16 + use bevy_ratatui::event::KeyMessage; 24 17 25 18 use crate::{ 26 - device::{Device, DevicePlugin, DeviceSocket, SearchingDevices}, 19 + device::{DevicePlugin, SearchingDevices}, 27 20 net::{MdnsSignaler, NetPlugin}, 28 21 state::AppState, 22 + views::HomeViewPlugin, 29 23 }; 30 24 31 25 #[derive(Debug)] ··· 35 29 fn build(&self, app: &mut bevy::app::App) { 36 30 app.init_resource::<SearchingDevices>() 37 31 .init_state::<AppState>() 38 - .add_plugins((NetPlugin, DevicePlugin)) 32 + .add_plugins((NetPlugin, DevicePlugin, HomeViewPlugin)) 39 33 .add_systems(PreUpdate, keybinds) 40 - .add_systems(Update, search_timer) 41 - .add_systems(PostUpdate, home_view.run_if(in_state(AppState::Home))); 34 + .add_systems(Update, search_timer); 42 35 } 43 36 } 44 37 ··· 80 73 } 81 74 } 82 75 } 83 - 84 - fn home_view( 85 - mut context: ResMut<RatatuiContext>, 86 - is_searching: Res<SearchingDevices>, 87 - q_devices: Query<(&Name, &DeviceSocket), With<Device>>, 88 - ) -> Result { 89 - context.draw(|frame| { 90 - let [top, bottom] = 91 - Layout::vertical([Constraint::Length(3), Constraint::Fill(1)]).areas(frame.area()); 92 - 93 - let searching = if is_searching.searching.is_some() { 94 - "Searching..." 95 - } else { 96 - "Select a Device" 97 - }; 98 - let paragraph = Paragraph::new(searching).block( 99 - Block::bordered() 100 - .padding(Padding::horizontal(2)) 101 - .title("Striker") 102 - .title_alignment(HorizontalAlignment::Center), 103 - ); 104 - 105 - let items = q_devices 106 - .iter() 107 - .map(|(name, addr)| ListItem::new(format!("{}, {}:{}", name, addr.address, addr.port))); 108 - 109 - let list = List::new(items) 110 - .direction(ListDirection::TopToBottom) 111 - .block(Block::bordered().title("Devices")); 112 - 113 - frame.render_widget(paragraph, top); 114 - frame.render_widget(list, bottom); 115 - })?; 116 - 117 - Ok(()) 118 - }
+17
src/views.rs
··· 1 + use bevy::{ 2 + app::{Plugin, PostUpdate}, 3 + ecs::schedule::IntoScheduleConfigs, 4 + state::condition::in_state, 5 + }; 6 + 7 + use crate::state::AppState; 8 + 9 + pub mod home; 10 + 11 + pub struct HomeViewPlugin; 12 + 13 + impl Plugin for HomeViewPlugin { 14 + fn build(&self, app: &mut bevy::app::App) { 15 + app.add_systems(PostUpdate, home::home_view.run_if(in_state(AppState::Home))); 16 + } 17 + }
+56
src/views/home.rs
··· 1 + use bevy::ecs::{ 2 + error::Result, 3 + name::Name, 4 + query::With, 5 + system::{Query, Res, ResMut}, 6 + }; 7 + use bevy_ratatui::RatatuiContext; 8 + use ratatui::{ 9 + layout::{Constraint, HorizontalAlignment, Layout}, 10 + style::Color, 11 + widgets::{Block, List, ListDirection, ListItem, Padding, Paragraph}, 12 + }; 13 + 14 + use crate::device::{Device, DeviceSocket, SearchingDevices}; 15 + 16 + pub fn home_view( 17 + mut context: ResMut<RatatuiContext>, 18 + is_searching: Res<SearchingDevices>, 19 + q_devices: Query<(&Name, &DeviceSocket), With<Device>>, 20 + ) -> Result { 21 + context.draw(|frame| { 22 + let [top, bottom] = 23 + Layout::vertical([Constraint::Length(3), Constraint::Fill(1)]).areas(frame.area()); 24 + 25 + let searching = if is_searching.searching.is_some() { 26 + "Searching..." 27 + } else { 28 + "Select a Device" 29 + }; 30 + let paragraph = Paragraph::new(searching).block( 31 + Block::bordered() 32 + .padding(Padding::horizontal(2)) 33 + .title("Striker") 34 + .title_alignment(HorizontalAlignment::Center) 35 + .border_style(Color::LightBlue), 36 + ); 37 + 38 + let items = q_devices 39 + .iter() 40 + .map(|(name, addr)| ListItem::new(format!("{}, {}:{}", name, addr.address, addr.port))); 41 + 42 + let list = List::new(items) 43 + .direction(ListDirection::TopToBottom) 44 + .block( 45 + Block::bordered() 46 + .title("Devices") 47 + .padding(Padding::new(2, 2, 1, 1)) 48 + .border_style(Color::LightBlue), 49 + ); 50 + 51 + frame.render_widget(paragraph, top); 52 + frame.render_widget(list, bottom); 53 + })?; 54 + 55 + Ok(()) 56 + }