rat_widget/calendar/
calendar3.rs1use crate::calendar::{CalendarSelection, CalendarState, CalendarStyle, Month};
2use chrono::NaiveDate;
3use ratatui::buffer::Buffer;
4use ratatui::layout::{Alignment, Direction, Rect};
5use ratatui::style::Style;
6use ratatui::widgets::{Block, StatefulWidget};
7use std::collections::HashMap;
8use std::marker::PhantomData;
9use std::mem;
10
11#[derive(Debug, Default)]
52pub struct Calendar3<'a, Selection> {
53 direction: Direction,
54 months: [Month<'a, Selection>; 3],
55 phantom: PhantomData<Selection>,
56}
57
58impl<'a, Selection> Calendar3<'a, Selection> {
59 pub fn new() -> Self
60 where
61 Selection: Default,
62 {
63 Self::default()
64 }
65
66 #[inline]
68 pub fn locale(mut self, loc: chrono::Locale) -> Self {
69 for i in 0..3 {
70 self.months[i] = mem::take(&mut self.months[i]).locale(loc);
71 }
72 self
73 }
74
75 #[inline]
76 pub fn direction(mut self, direction: Direction) -> Self {
77 self.direction = direction;
78 self
79 }
80
81 #[inline]
83 pub fn show_weekdays(mut self) -> Self {
84 for i in 0..3 {
85 self.months[i] = mem::take(&mut self.months[i]).show_weekdays();
86 }
87 self
88 }
89
90 #[inline]
92 pub fn styles(mut self, s: CalendarStyle) -> Self {
93 for i in 0..3 {
94 self.months[i] = mem::take(&mut self.months[i]).styles(s.clone());
95 }
96 self
97 }
98
99 pub fn select_style(mut self, style: Style) -> Self {
101 for i in 0..3 {
102 self.months[i] = mem::take(&mut self.months[i]).select_style(style);
103 }
104 self
105 }
106
107 pub fn focus_style(mut self, style: Style) -> Self {
109 for i in 0..3 {
110 self.months[i] = mem::take(&mut self.months[i]).focus_style(style);
111 }
112 self
113 }
114
115 #[inline]
117 pub fn day_style(mut self, s: impl Into<Style>) -> Self {
118 let s = s.into();
119 for i in 0..3 {
120 self.months[i] = mem::take(&mut self.months[i]).day_style(s);
121 }
122 self
123 }
124
125 #[inline]
127 pub fn day_styles(mut self, styles: &'a HashMap<NaiveDate, Style>) -> Self {
128 for i in 0..3 {
129 self.months[i] = mem::take(&mut self.months[i]).day_styles(styles);
130 }
131 self
132 }
133
134 #[inline]
136 pub fn week_style(mut self, s: impl Into<Style>) -> Self {
137 let s = s.into();
138 for i in 0..3 {
139 self.months[i] = mem::take(&mut self.months[i]).week_style(s);
140 }
141 self
142 }
143
144 #[inline]
146 pub fn weekday_style(mut self, s: impl Into<Style>) -> Self {
147 let s = s.into();
148 for i in 0..3 {
149 self.months[i] = mem::take(&mut self.months[i]).weekday_style(s);
150 }
151 self
152 }
153
154 #[inline]
156 pub fn title_style(mut self, s: impl Into<Style>) -> Self {
157 let s = s.into();
158 for i in 0..3 {
159 self.months[i] = mem::take(&mut self.months[i]).title_style(s);
160 }
161 self
162 }
163
164 #[inline]
166 pub fn title_align(mut self, a: Alignment) -> Self {
167 for i in 0..3 {
168 self.months[i] = mem::take(&mut self.months[i]).title_align(a);
169 }
170 self
171 }
172
173 #[inline]
175 pub fn block(mut self, b: Block<'a>) -> Self {
176 for i in 0..3 {
177 self.months[i] = mem::take(&mut self.months[i]).block(b.clone());
178 }
179 self
180 }
181}
182
183impl<Selection> StatefulWidget for Calendar3<'_, Selection>
184where
185 Selection: CalendarSelection,
186{
187 type State = CalendarState<3, Selection>;
188
189 #[allow(deprecated)]
190 fn render(mut self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
191 state.area = area;
192 state.inner = area;
193 state.widget_area = area;
194
195 match self.direction {
196 Direction::Horizontal => {
197 let width = self.months[0].width();
198 let height = self
199 .months
200 .iter()
201 .enumerate()
202 .map(|(i, v)| v.height(&state.months[i]))
203 .max()
204 .expect("height");
205
206 let mut area = Rect::new(area.x, area.y, width, height);
207 for i in 0..3 {
208 mem::take(&mut self.months[i]).render(area, buf, &mut state.months[i]);
209 area.x += area.width + 2;
210 }
211 }
212 Direction::Vertical => {
213 let width = self.months[0].width();
214
215 let mut area = Rect::new(area.x, area.y, width, 0);
216 for i in 0..3 {
217 area.height = self.months[i].height(&state.months[0]);
218 mem::take(&mut self.months[i]).render(area, buf, &mut state.months[i]);
219 area.y += area.height + 1;
220 }
221 }
222 }
223 }
224}