rat_widget/calendar/
no_selection.rs

1use crate::calendar::event::CalOutcome;
2use crate::calendar::{CalendarSelection, CalendarState, MonthState};
3use chrono::NaiveDate;
4use rat_event::{ct_event, ConsumedEvent, HandleEvent, MouseOnly, Regular};
5use rat_focus::HasFocus;
6
7/// No selection model
8///
9/// Can scroll the calendar with Up/Down, PageUp/PageDown though.
10/// Ctrl+Home moves to today.
11///
12#[derive(Debug, Default, Clone)]
13pub struct NoSelection;
14
15impl CalendarSelection for NoSelection {
16    fn count(&self) -> usize {
17        0
18    }
19
20    fn is_selected(&self, _: NaiveDate) -> bool {
21        false
22    }
23
24    fn lead_selection(&self) -> Option<NaiveDate> {
25        None
26    }
27}
28
29impl HandleEvent<crossterm::event::Event, Regular, CalOutcome> for MonthState<NoSelection> {
30    fn handle(&mut self, event: &crossterm::event::Event, _qualifier: Regular) -> CalOutcome {
31        self.handle(event, MouseOnly)
32    }
33}
34
35impl HandleEvent<crossterm::event::Event, MouseOnly, CalOutcome> for MonthState<NoSelection> {
36    fn handle(&mut self, _event: &crossterm::event::Event, _qualifier: MouseOnly) -> CalOutcome {
37        CalOutcome::Continue
38    }
39}
40
41impl<const N: usize> HandleEvent<crossterm::event::Event, Regular, CalOutcome>
42    for CalendarState<N, NoSelection>
43{
44    fn handle(&mut self, event: &crossterm::event::Event, _qualifier: Regular) -> CalOutcome {
45        let mut r = 'f: {
46            for month in &mut self.months {
47                let r = month.handle(event, Regular);
48                if r == CalOutcome::Selected {
49                    self.focus_lead();
50                    break 'f r;
51                }
52            }
53            CalOutcome::Continue
54        };
55
56        r = r.or_else(|| {
57            if self.is_focused() {
58                match event {
59                    ct_event!(keycode press CONTROL-Home) => self.move_to_today(),
60                    ct_event!(keycode press PageUp) => self.prev_month(1),
61                    ct_event!(keycode press PageDown) => self.next_month(1),
62                    ct_event!(keycode press Up) => self.prev_month(1),
63                    ct_event!(keycode press Down) => self.next_month(1),
64                    _ => CalOutcome::Continue,
65                }
66            } else {
67                CalOutcome::Continue
68            }
69        });
70
71        r.or_else(|| self.handle(event, MouseOnly))
72    }
73}
74
75impl<const N: usize> HandleEvent<crossterm::event::Event, MouseOnly, CalOutcome>
76    for CalendarState<N, NoSelection>
77{
78    fn handle(&mut self, event: &crossterm::event::Event, _qualifier: MouseOnly) -> CalOutcome {
79        for i in 0..self.months.len() {
80            if self.months[i].gained_focus() {
81                self.set_primary_idx(i);
82                break;
83            }
84        }
85
86        let all_areas = self
87            .months
88            .iter()
89            .map(|v| v.area)
90            .reduce(|v, w| v.union(w))
91            .unwrap_or_default();
92        match event {
93            ct_event!(scroll up for x,y) if all_areas.contains((*x, *y).into()) => {
94                self.scroll_back(self.step())
95            }
96            ct_event!(scroll down for x,y) if all_areas.contains((*x, *y).into()) => {
97                self.scroll_forward(self.step())
98            }
99            _ => CalOutcome::Continue,
100        }
101    }
102}