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