ui.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. use crate::view::View;
  2. use log::debug;
  3. use tui::{
  4. backend::Backend,
  5. layout::{Alignment, Constraint, Direction, Layout},
  6. style::Style,
  7. text::{Span, Spans},
  8. widgets::{Block, Borders, List, ListItem, Paragraph},
  9. Frame,
  10. };
  11. // create top level outgoing widget
  12. pub fn make_oframe() -> NetFrame {
  13. let ot_len = 4;
  14. let ot_width = 8;
  15. let ot_align = Alignment::Left;
  16. let ot_cnstrnt = vec![Constraint::Percentage(100)];
  17. let ot_widget = NetWidget::new(ot_len, ot_width, ot_align, ot_cnstrnt);
  18. let om_len = 5;
  19. let om_width = 8;
  20. let om_align = Alignment::Right;
  21. let om_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  22. let om_widget = NetWidget::new(om_len, om_width, om_align, om_cnstrnt);
  23. let os_len = 5;
  24. let os_width = 10;
  25. let os_align = Alignment::Left;
  26. let os_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  27. let os_widget = NetWidget::new(os_len, os_width, os_align, os_cnstrnt);
  28. let oframe = NetFrame::new(ot_widget, os_widget, om_widget);
  29. oframe
  30. }
  31. // create top level ingoing widget
  32. pub fn make_iframe(oframe: NetFrame) -> NetFrame {
  33. let it_len = oframe.addrs.len;
  34. let it_width = 8;
  35. let it_align = Alignment::Left;
  36. let it_cnstrnt = vec![Constraint::Percentage(100)];
  37. let it_widget = NetWidget::new(it_len, it_width, it_align, it_cnstrnt);
  38. let is_len = oframe.addrs.len + oframe.title.len + 1;
  39. let is_width = 10;
  40. let is_align = Alignment::Left;
  41. let is_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  42. let is_widget = NetWidget::new(is_len, is_width, is_align, is_cnstrnt);
  43. let im_len = is_len;
  44. let im_width = 8;
  45. let im_align = Alignment::Right;
  46. let im_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  47. let im_widget = NetWidget::new(im_len, im_width, im_align, im_cnstrnt);
  48. let iframe = NetFrame::new(it_widget, is_widget, im_widget);
  49. iframe
  50. }
  51. // create top level manual widget
  52. pub fn make_mframe(iframe: NetFrame) -> NetFrame {
  53. let mt_len = iframe.title.len + iframe.addrs.len + 1;
  54. let mt_width = 8;
  55. let mt_align = Alignment::Left;
  56. let mt_cnstrnt = vec![Constraint::Percentage(100)];
  57. let mt_widget = NetWidget::new(mt_len, mt_width, mt_align, mt_cnstrnt);
  58. let mk_len = mt_len + 1;
  59. let mk_width = 10;
  60. let mk_align = Alignment::Left;
  61. let mk_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  62. let mk_widget = NetWidget::new(mk_len, mk_width, mk_align, mk_cnstrnt);
  63. let mm_len = mt_len + 1;
  64. let mm_width = 10;
  65. let mm_align = Alignment::Left;
  66. let mm_cnstrnt = vec![Constraint::Percentage(45), Constraint::Percentage(55)];
  67. let mm_widget = NetWidget::new(mm_len, mm_width, mm_align, mm_cnstrnt);
  68. let mframe = NetFrame::new(mt_widget.clone(), mk_widget.clone(), mm_widget);
  69. mframe
  70. }
  71. pub fn ui<B: Backend>(f: &mut Frame<'_, B>, mut view: View) {
  72. let oframe = make_oframe();
  73. get_and_draw_outbound(f, view.clone(), oframe.clone());
  74. let iframe = make_iframe(oframe.clone());
  75. get_and_draw_inbound(f, view.clone(), iframe.clone(), oframe.clone());
  76. let mframe = make_mframe(iframe.clone());
  77. draw_manual(f, view.clone(), mframe.clone());
  78. let top_widget = ListObject::new(oframe, iframe, mframe);
  79. let list_margin = 2;
  80. let list_direction = Direction::Horizontal;
  81. let list_cnstrnts = vec![Constraint::Percentage(50), Constraint::Percentage(50)];
  82. let prev_len = top_widget.manual.addrs.len;
  83. //draw_list(list_margin, prev_len, list_direction, list_cnstrnts, view.clone(), top_widget, f);
  84. let mut nodes = Vec::new();
  85. for id in &view.id_list.node_id {
  86. let mut lines = vec![Spans::from(id.to_string())];
  87. for _i in 1..prev_len {
  88. lines.push(Spans::from(""));
  89. }
  90. let ids = ListItem::new(lines).style(Style::default());
  91. nodes.push(ids)
  92. }
  93. let nodes =
  94. List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
  95. // this is just the box around the list. not the actual list
  96. let slice = Layout::default()
  97. .direction(list_direction)
  98. .margin(list_margin)
  99. .constraints(list_cnstrnts)
  100. .split(f.size());
  101. f.render_stateful_widget(nodes, slice[0], &mut view.id_list.state);
  102. //render_info_right(view.clone(), f, slice);
  103. }
  104. //fn render_info_right<B: Backend>(_view: View, f: &mut Frame<'_, B>, slice: Vec<Rect>) {
  105. // let span = vec![];
  106. // let graph =
  107. // Paragraph::new(span).block(Block::default().borders(Borders::ALL)).style(Style::default());
  108. // f.render_widget(graph, slice[1]);
  109. //}
  110. // Top level widget
  111. #[derive(Clone)]
  112. pub struct ListObject {
  113. pub outbound: NetFrame,
  114. pub inbound: NetFrame,
  115. pub manual: NetFrame,
  116. }
  117. impl ListObject {
  118. pub fn new(outbound: NetFrame, inbound: NetFrame, manual: NetFrame) -> ListObject {
  119. ListObject { outbound, inbound, manual }
  120. }
  121. }
  122. // Middle level widgets
  123. #[derive(Clone)]
  124. pub struct NetFrame {
  125. pub title: NetWidget,
  126. pub addrs: NetWidget,
  127. pub msgs: NetWidget,
  128. }
  129. impl NetFrame {
  130. pub fn new(title: NetWidget, addrs: NetWidget, msgs: NetWidget) -> NetFrame {
  131. NetFrame { title, addrs, msgs }
  132. }
  133. pub fn get_total_len(self) -> usize {
  134. let t_len = self.title.len;
  135. let a_len = self.addrs.len;
  136. let m_len = self.msgs.len;
  137. let total_len = t_len + a_len + m_len;
  138. total_len
  139. }
  140. }
  141. // Lowest level widgets
  142. #[derive(Clone)]
  143. pub struct NetWidget {
  144. pub len: usize,
  145. pub width: usize,
  146. pub align: Alignment,
  147. pub cnstrnts: Vec<Constraint>,
  148. }
  149. impl NetWidget {
  150. pub fn new(len: usize, width: usize, align: Alignment, cnstrnts: Vec<Constraint>) -> NetWidget {
  151. NetWidget { len, width, align, cnstrnts }
  152. }
  153. pub fn update(mut self, len: usize) {
  154. self.len = len
  155. }
  156. pub fn draw<B: Backend>(self, vec: Vec<Spans>, f: &mut Frame<'_, B>) {
  157. let slice = Layout::default()
  158. .direction(Direction::Horizontal)
  159. .horizontal_margin(self.width as u16)
  160. .vertical_margin(self.len as u16)
  161. .constraints(self.cnstrnts.as_ref())
  162. .split(f.size());
  163. let graph = Paragraph::new(vec).style(Style::default()).alignment(self.align);
  164. f.render_widget(graph, slice[0]);
  165. }
  166. pub fn get_len(self) -> usize {
  167. return self.len;
  168. }
  169. }
  170. // loop through all connected nodes in Model
  171. // parse outbound data by creating a text object called Vec<Spans>
  172. // send Vec<Spans> to render_widget()
  173. fn get_and_draw_outbound<B: Backend>(f: &mut Frame<'_, B>, view: View, oframe: NetFrame) {
  174. let mut titles = Vec::new();
  175. let mut msgs = Vec::new();
  176. let mut slots = Vec::new();
  177. let mut data = Vec::new();
  178. titles.push(Spans::from(Span::styled("Outgoing", Style::default())));
  179. data.push("Outgoing".to_string());
  180. for id in &view.id_list.node_id {
  181. //debug!("Looping through nodes: {}", id);
  182. match &view.info_list.infos.get(id) {
  183. Some(connects) => {
  184. // there is only a single outbound connection so this works
  185. // this is probably a bug lol
  186. for slot in &connects.outbound[0].slots {
  187. if slot.addr.is_empty() {
  188. slots.push(Spans::from(format!("Empty")));
  189. data.push("empty".to_string());
  190. } else {
  191. slots.push(Spans::from(format!("{}", slot.addr)));
  192. data.push(format!("{}", slot.addr));
  193. }
  194. match slot.channel.last_status.as_str() {
  195. "recv" => {
  196. msgs.push(Spans::from(format!("[R: {}]", slot.channel.last_msg)));
  197. data.push(format!("{}", slot.channel.last_msg));
  198. }
  199. "sent" => {
  200. msgs.push(Spans::from(format!("[S: {}]", slot.channel.last_msg)));
  201. data.push(format!("{}", slot.channel.last_msg));
  202. }
  203. e => {
  204. //debug!("data getting lost {}", e);
  205. // TODO: right now we do nothing with these values
  206. }
  207. }
  208. }
  209. }
  210. None => {
  211. debug!("NONE VALUE TRIGGERD");
  212. // TODO: Error
  213. }
  214. }
  215. }
  216. //debug!("{:?}", data);
  217. oframe.title.clone().draw(titles.clone(), f);
  218. let t_len2 = titles.clone().len();
  219. oframe.title.clone().update(t_len2);
  220. oframe.addrs.clone().draw(slots.clone(), f);
  221. let s_len2 = slots.clone().len();
  222. oframe.addrs.clone().update(s_len2);
  223. oframe.msgs.clone().draw(msgs.clone(), f);
  224. let m_len2 = msgs.clone().len();
  225. oframe.msgs.clone().update(m_len2);
  226. }
  227. fn print_type_of<T>(_: &T) {
  228. debug!("{}", std::any::type_name::<T>())
  229. }
  230. // loop through all connected nodes in Model
  231. // parse inbound data by creating a text object called Vec<Spans>
  232. // send Vec<Spans> to render_widget()
  233. fn get_and_draw_inbound<B: Backend>(
  234. f: &mut Frame<'_, B>,
  235. view: View,
  236. iframe: NetFrame,
  237. outframe: NetFrame,
  238. ) {
  239. let slots_len = outframe.addrs.get_len();
  240. let mut titles = Vec::new();
  241. let mut addrs = Vec::new();
  242. let mut msgs = Vec::new();
  243. let mut data = Vec::new();
  244. // need to have access to slots_len
  245. for _i in 1..slots_len {
  246. titles.push(Spans::from(""));
  247. }
  248. titles.push(Spans::from(Span::styled("Incoming", Style::default())));
  249. data.push("Incoming".to_string());
  250. for id in &view.id_list.node_id {
  251. //debug!("Looping through nodes: {}", id);
  252. match &view.info_list.infos.get(id) {
  253. Some(node) => {
  254. data.push(id.to_string());
  255. for connect in &node.inbound {
  256. addrs.push(Spans::from(connect.connected.clone()));
  257. data.push(connect.connected.clone());
  258. match connect.channel.last_status.as_str() {
  259. "recv" => {
  260. data.push("".to_string());
  261. msgs.push(Spans::from(format!("[R: {}]", connect.channel.last_msg)));
  262. data.push(format!("[R: {}]", connect.channel.last_msg));
  263. }
  264. "sent" => {
  265. data.push("".to_string());
  266. msgs.push(Spans::from(format!("[S: {}]", connect.channel.last_msg)));
  267. data.push(format!("[S: {}]", connect.channel.last_msg));
  268. }
  269. "Null" => {
  270. data.push("Null".to_string());
  271. }
  272. _ => {
  273. // TODO
  274. debug!("This is a bug");
  275. }
  276. }
  277. }
  278. }
  279. None => {
  280. debug!("NONE VALUE TRIGGERD");
  281. // This should never happen. TODO: make this an error.
  282. }
  283. }
  284. }
  285. //debug!("{:?}", data);
  286. iframe.title.clone().draw(titles.clone(), f);
  287. let t_len2 = titles.clone().len();
  288. iframe.title.clone().update(t_len2);
  289. iframe.addrs.clone().draw(addrs.clone(), f);
  290. let s_len2 = addrs.clone().len();
  291. iframe.addrs.clone().update(s_len2);
  292. iframe.msgs.clone().draw(msgs.clone(), f);
  293. let m_len2 = msgs.clone().len();
  294. iframe.msgs.clone().update(m_len2);
  295. }
  296. fn draw_manual<B: Backend>(f: &mut Frame<'_, B>, view: View, mframe: NetFrame) {
  297. let mut titles = Vec::new();
  298. let mut keys = Vec::new();
  299. titles.push(Spans::from(Span::styled("Manual", Style::default())));
  300. for id in &view.id_list.node_id {
  301. match &view.info_list.infos.get(id) {
  302. Some(connects) => {
  303. for _conn in &connects.manual {
  304. keys.push(Spans::from(format!("{}", connects.manual[0].key)));
  305. }
  306. }
  307. None => {
  308. // TODO
  309. }
  310. }
  311. }
  312. mframe.title.clone().draw(titles.clone(), f);
  313. let t_len2 = titles.clone().len();
  314. mframe.title.clone().update(t_len2);
  315. mframe.addrs.clone().draw(keys.clone(), f);
  316. let s_len2 = keys.clone().len();
  317. mframe.addrs.clone().update(s_len2);
  318. }
  319. //fn draw_list<B: Backend>(
  320. // margin: u16,
  321. // prev_len: usize,
  322. // direction: Direction,
  323. // cnstrnts: Vec<Constraint>,
  324. // mut view: View,
  325. // connects: ListObject,
  326. // f: &mut Frame<'_, B>,
  327. //) {
  328. // let mut nodes = Vec::new();
  329. //
  330. // for id in &view.id_list.node_id {
  331. // let mut lines = vec![Spans::from(id.to_string())];
  332. // // need total_len
  333. // // process_outbound
  334. // // process_inbound
  335. // // process_manual
  336. // for _i in 1..prev_len {
  337. // lines.push(Spans::from(""));
  338. // }
  339. // let ids = ListItem::new(lines).style(Style::default());
  340. // nodes.push(ids)
  341. // }
  342. //
  343. // let nodes =
  344. // List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
  345. // // this is just the box around the list. not the actual list
  346. // let slice =
  347. // Layout::default().direction(direction).margin(margin).constraints(cnstrnts).split(f.size());
  348. //
  349. // f.render_stateful_widget(nodes, slice[0], &mut view.id_list.state);
  350. //}