}
impl TextFragment for FileStatusLineFinal {
- fn render(&self, _width: usize) -> Vec<ColouredString> {
- vec! {
- ColouredString::plain("FIXME"),
+ fn render(&self, width: usize) -> Vec<ColouredString> {
+ let mut line = ColouredString::plain("");
+ let space = ColouredString::plain(" ").repeat(FileStatusLine::SPACING);
+ let push = |line: &mut ColouredString, s: ColouredStringSlice<'_>| {
+ if !line.is_empty() {
+ line.push_str(&space.slice());
+ }
+ line.push_str(&s);
+ };
+
+ if let Some(msg) = &self.fs.message {
+ let cmsg = ColouredString::plain(&msg);
+ push(&mut line, cmsg.slice());
+ }
+
+ let cprop = if let Some(prop) = &self.fs.proportion {
+ Some(ColouredString::plain(&format!("({}%)", prop)))
+ } else {
+ None
+ };
+ let cpropwidth = if let Some(cprop) = &cprop { cprop.width() } else {0};
+ let extraspace = if !line.is_empty() && cpropwidth > 0 {
+ FileStatusLine::SPACING
+ } else {0};
+
+ let avail = width - min(
+ width, line.width() + cpropwidth + extraspace + 1);
+ let minindex = self.priwidth.partition_point(|(_, w)| *w <= avail);
+ dbg!(avail, &self.priwidth, minindex);
+ if minindex > 0 {
+ let minpri = self.priwidth[minindex - 1].0;
+
+ for (kp, pri) in &self.fs.keypresses {
+ if *pri >= minpri {
+ let mut ckey = ColouredString::plain("[");
+ let ckp = ColouredString::uniform(&kp.key, 'k');
+ ckey.push_str(&ckp.slice());
+ ckey.push_str(&ColouredString::plain("]:").slice());
+ ckey.push_str(&kp.description.slice());
+ push(&mut line, ckey.slice());
+ }
+
+ }
+ }
+
+ if let Some(cprop) = cprop {
+ push(&mut line, cprop.slice());
}
+
+ // Done. Now centre it in the available space.
+ let line = line.truncate(width - 1);
+ let space = width - min(line.width() + 1, width);
+ let left = space / 2;
+ let linepad = ColouredString::plain(" ").repeat(left) + line;
+ vec! { linepad }
}
}
+#[test]
+fn test_filestatus_render() {
+ let fs = FileStatusLine::new()
+ .message("stoat")
+ .set_proportion(34, 55)
+ .add("A".to_owned(), "Annoy", 10)
+ .add("B".to_owned(), "Badger", 10)
+ .add("C".to_owned(), "Critical", 1000)
+ .add("D".to_owned(), "Dull", 1)
+ .into_box();
+
+ assert_eq!(fs.render(80), vec! {
+ ColouredString::general(
+ " stoat [A]:Annoy [B]:Badger [C]:Critical [D]:Dull (61%)",
+ " k k k k "),
+ });
+
+ assert_eq!(fs.render(60), vec! {
+ ColouredString::general(
+ "stoat [A]:Annoy [B]:Badger [C]:Critical [D]:Dull (61%)",
+ " k k k k "),
+ });
+
+ assert_eq!(fs.render(59), vec! {
+ ColouredString::general(
+ " stoat [A]:Annoy [B]:Badger [C]:Critical (61%)",
+ " k k k "),
+ });
+
+ assert_eq!(fs.render(50), vec! {
+ ColouredString::general(
+ "stoat [A]:Annoy [B]:Badger [C]:Critical (61%)",
+ " k k k "),
+ });
+
+ assert_eq!(fs.render(49), vec! {
+ ColouredString::general(
+ " stoat [C]:Critical (61%)",
+ " k "),
+ });
+
+ assert_eq!(fs.render(27), vec! {
+ ColouredString::general(
+ "stoat [C]:Critical (61%)",
+ " k "),
+ });
+
+ assert_eq!(fs.render(26), vec! {
+ ColouredString::plain(" stoat (61%)"),
+ });
+
+ let fs = FileStatusLine::new()
+ .set_proportion(1, 11)
+ .add("K".to_owned(), "Keypress", 10)
+ .into_box();
+
+ assert_eq!(fs.render(19), vec! {
+ ColouredString::general(
+ "[K]:Keypress (9%)",
+ " k "),
+ });
+
+ assert_eq!(fs.render(18), vec! {
+ ColouredString::general(
+ " (9%)",
+ " "),
+ });
+
+ let fs = FileStatusLine::new()
+ .message("weasel")
+ .add("K".to_owned(), "Keypress", 10)
+ .into_box();
+
+ assert_eq!(fs.render(21), vec! {
+ ColouredString::general(
+ "weasel [K]:Keypress",
+ " k "),
+ });
+
+ assert_eq!(fs.render(20), vec! {
+ ColouredString::general(
+ " weasel",
+ " "),
+ });
+}
+
// TODO:
// MenuKeypressLine