Skip to main content

ctl_layout/
breakpoint.rs

1//! One widget below a width and another from it up.
2
3use ctl_text::{Context, Line, Measurement, Renderable};
4
5/// One widget below a width and another from it up.
6///
7/// It measures and renders whichever widget applies at the context's width,
8/// so a table can give way to [`Definitions`](crate::Definitions) on a narrow
9/// terminal. Each widget holds the data it draws, owned or borrowed:
10/// `Breakpoint::new(40, &definitions, &table)` works.
11#[derive(Clone, Debug)]
12pub struct Breakpoint<N, W> {
13    threshold: u16,
14    narrow: N,
15    wide: W,
16}
17
18impl<N: Renderable, W: Renderable> Breakpoint<N, W> {
19    /// `narrow` when the width is under `threshold` cells, `wide` at
20    /// `threshold` and above.
21    #[must_use]
22    pub fn new(threshold: u16, narrow: N, wide: W) -> Self {
23        Self {
24            threshold,
25            narrow,
26            wide,
27        }
28    }
29
30    fn pick(&self, context: &Context) -> &dyn Renderable {
31        if context.width() < self.threshold {
32            &self.narrow
33        } else {
34            &self.wide
35        }
36    }
37}
38
39impl<N: Renderable, W: Renderable> Renderable for Breakpoint<N, W> {
40    fn measure(&self, context: &Context) -> Measurement {
41        self.pick(context).measure(context)
42    }
43
44    fn render(&self, context: &Context) -> Vec<Line> {
45        self.pick(context).render(context)
46    }
47}