1use crate::Scheme;
6use rat_widget::button::ButtonStyle;
7use rat_widget::calendar::CalendarStyle;
8use rat_widget::checkbox::CheckboxStyle;
9use rat_widget::choice::ChoiceStyle;
10use rat_widget::clipper::ClipperStyle;
11use rat_widget::file_dialog::FileDialogStyle;
12use rat_widget::line_number::LineNumberStyle;
13use rat_widget::list::ListStyle;
14use rat_widget::menu::MenuStyle;
15use rat_widget::msgdialog::MsgDialogStyle;
16#[allow(deprecated)]
17use rat_widget::pager::PagerStyle;
18use rat_widget::paragraph::ParagraphStyle;
19use rat_widget::popup::PopupStyle;
20use rat_widget::radio::{RadioLayout, RadioStyle};
21use rat_widget::scrolled::ScrollStyle;
22use rat_widget::shadow::{ShadowDirection, ShadowStyle};
23use rat_widget::splitter::SplitStyle;
24use rat_widget::tabbed::TabbedStyle;
25use rat_widget::table::TableStyle;
26use rat_widget::text::TextStyle;
27use rat_widget::view::ViewStyle;
28use ratatui::style::Color;
29use ratatui::style::{Style, Stylize};
30use ratatui::widgets::{Block, Borders};
31use std::time::Duration;
32
33#[derive(Debug, Clone)]
41pub struct DarkTheme {
42 s: Scheme,
43 name: String,
44}
45
46impl DarkTheme {
47 pub fn new(name: String, s: Scheme) -> Self {
48 Self { s, name }
49 }
50}
51
52impl DarkTheme {
53 pub fn name(&self) -> &str {
55 &self.name
56 }
57
58 pub fn dark_theme(&self) -> bool {
60 true
61 }
62
63 pub fn scheme(&self) -> &Scheme {
65 &self.s
66 }
67
68 pub fn style(&self, bg: Color) -> Style {
70 self.s.style(bg)
71 }
72
73 pub fn true_dark_style(&self, bg: Color) -> Style {
78 self.s.style(self.s.true_dark_color(bg))
79 }
80
81 pub fn grey_style(&self, bg: Color) -> Style {
84 self.s.style(self.s.grey_color(bg))
85 }
86
87 pub fn white(&self, n: usize) -> Style {
90 self.s.style(self.s.white[n])
91 }
92
93 pub fn black(&self, n: usize) -> Style {
96 self.s.style(self.s.black[n])
97 }
98
99 pub fn gray(&self, n: usize) -> Style {
102 self.s.style(self.s.gray[n])
103 }
104
105 pub fn red(&self, n: usize) -> Style {
108 self.s.style(self.s.red[n])
109 }
110
111 pub fn orange(&self, n: usize) -> Style {
114 self.s.style(self.s.orange[n])
115 }
116
117 pub fn yellow(&self, n: usize) -> Style {
120 self.s.style(self.s.yellow[n])
121 }
122
123 pub fn limegreen(&self, n: usize) -> Style {
126 self.s.style(self.s.limegreen[n])
127 }
128
129 pub fn green(&self, n: usize) -> Style {
132 self.s.style(self.s.green[n])
133 }
134
135 pub fn bluegreen(&self, n: usize) -> Style {
138 self.s.style(self.s.bluegreen[n])
139 }
140
141 pub fn cyan(&self, n: usize) -> Style {
144 self.s.style(self.s.cyan[n])
145 }
146
147 pub fn blue(&self, n: usize) -> Style {
150 self.s.style(self.s.blue[n])
151 }
152
153 pub fn deepblue(&self, n: usize) -> Style {
156 self.s.style(self.s.deepblue[n])
157 }
158
159 pub fn purple(&self, n: usize) -> Style {
162 self.s.style(self.s.purple[n])
163 }
164
165 pub fn magenta(&self, n: usize) -> Style {
168 self.s.style(self.s.magenta[n])
169 }
170
171 pub fn redpink(&self, n: usize) -> Style {
174 self.s.style(self.s.redpink[n])
175 }
176
177 pub fn primary(&self, n: usize) -> Style {
180 self.s.style(self.s.primary[n])
181 }
182
183 pub fn secondary(&self, n: usize) -> Style {
186 self.s.style(self.s.secondary[n])
187 }
188
189 pub fn focus(&self) -> Style {
191 self.s.style(self.s.primary[2])
192 }
193
194 pub fn select(&self) -> Style {
196 self.s.style(self.s.secondary[1])
197 }
198
199 pub fn text_input(&self) -> Style {
201 self.s.style(self.s.gray[3])
202 }
203
204 pub fn text_focus(&self) -> Style {
206 self.s.style(self.s.primary[0])
207 }
208
209 pub fn text_select(&self) -> Style {
211 self.s.style(self.s.secondary[0])
212 }
213
214 pub fn container_base(&self) -> Style {
216 self.s.style(self.s.black[1])
217 }
218
219 pub fn container_border(&self) -> Style {
221 Style::default().fg(self.s.gray[0]).bg(self.s.black[1])
222 }
223
224 pub fn container_arrow(&self) -> Style {
226 Style::default().fg(self.s.secondary[0]).bg(self.s.black[1])
227 }
228
229 pub fn popup_base(&self) -> Style {
231 self.s.style(self.s.white[0])
232 }
233
234 pub fn popup_label(&self) -> Style {
236 self.s.style(self.s.white[0])
237 }
238
239 pub fn popup_border(&self) -> Style {
241 Style::default().fg(self.s.gray[0]).bg(self.s.white[0])
242 }
243
244 pub fn popup_arrow(&self) -> Style {
246 Style::default().fg(self.s.secondary[0]).bg(self.s.white[0])
247 }
248
249 pub fn dialog_base(&self) -> Style {
251 self.s.style(self.s.gray[1])
252 }
253
254 pub fn dialog_label(&self) -> Style {
256 self.s.style(self.s.gray[1])
257 }
258
259 pub fn dialog_border(&self) -> Style {
261 Style::default().fg(self.s.white[0]).bg(self.s.gray[1])
262 }
263
264 pub fn dialog_arrow(&self) -> Style {
266 Style::default().fg(self.s.secondary[2]).bg(self.s.gray[1])
267 }
268
269 pub fn status_base(&self) -> Style {
271 Style::default().fg(self.s.white[0]).bg(self.s.black[2])
272 }
273
274 pub fn button_base(&self) -> Style {
276 self.s.style(self.s.gray[2])
277 }
278
279 pub fn button_armed(&self) -> Style {
281 self.s.style(self.s.secondary[0])
282 }
283
284 pub fn month_style(&self) -> CalendarStyle {
286 CalendarStyle {
287 style: self.s.style(self.s.black[2]),
288 title: None,
289 weeknum: Some(Style::new().fg(self.s.limegreen[2])),
290 weekday: Some(Style::new().fg(self.s.limegreen[2])),
291 day: None,
292 select: Some(self.select()),
293 focus: Some(self.focus()),
294 ..CalendarStyle::default()
295 }
296 }
297
298 pub fn shadow_style(&self) -> ShadowStyle {
300 ShadowStyle {
301 style: Style::new().bg(self.s.black[0]),
302 dir: ShadowDirection::BottomRight,
303 ..ShadowStyle::default()
304 }
305 }
306
307 pub fn line_nr_style(&self) -> LineNumberStyle {
309 LineNumberStyle {
310 style: self.container_base().fg(self.s.gray[1]),
311 cursor: Some(self.text_select()),
312 ..LineNumberStyle::default()
313 }
314 }
315
316 pub fn textarea_style(&self) -> TextStyle {
318 TextStyle {
319 style: self.container_base(),
320 focus: Some(self.focus()),
321 select: Some(self.text_select()),
322 scroll: Some(self.scroll_style()),
323 border_style: Some(self.container_border()),
324 ..TextStyle::default()
325 }
326 }
327
328 pub fn text_style(&self) -> TextStyle {
330 TextStyle {
331 style: self.text_input(),
332 focus: Some(self.text_focus()),
333 select: Some(self.text_select()),
334 invalid: Some(Style::default().bg(self.s.red[3])),
335 ..TextStyle::default()
336 }
337 }
338
339 pub fn paragraph_style(&self) -> ParagraphStyle {
340 ParagraphStyle {
341 style: self.container_base(),
342 focus: Some(self.focus()),
343 scroll: Some(self.scroll_style()),
344 ..Default::default()
345 }
346 }
347
348 pub fn choice_style(&self) -> ChoiceStyle {
349 ChoiceStyle {
350 style: self.text_input(),
351 select: Some(self.text_focus()),
352 focus: Some(self.text_focus()),
353 popup_style: Some(self.popup_base()),
354 popup_border: Some(self.popup_border()),
355 popup_scroll: Some(self.popup_scroll_style()),
356 popup_block: Some(
357 Block::bordered()
358 .borders(Borders::LEFT)
359 .border_style(self.popup_border()),
360 ),
361 ..Default::default()
362 }
363 }
364
365 pub fn radio_style(&self) -> RadioStyle {
366 RadioStyle {
367 layout: Some(RadioLayout::Stacked),
368 style: self.text_input(),
369 focus: Some(self.text_focus()),
370 ..Default::default()
371 }
372 }
373
374 pub fn checkbox_style(&self) -> CheckboxStyle {
376 CheckboxStyle {
377 style: self.text_input(),
378 focus: Some(self.text_focus()),
379 ..Default::default()
380 }
381 }
382
383 pub fn menu_style(&self) -> MenuStyle {
385 let menu = Style::default().fg(self.s.white[3]).bg(self.s.black[2]);
386 MenuStyle {
387 style: menu,
388 title: Some(Style::default().fg(self.s.black[0]).bg(self.s.yellow[2])),
389 focus: Some(self.focus()),
390 right: Some(Style::default().fg(self.s.bluegreen[0])),
391 disabled: Some(Style::default().fg(self.s.gray[0])),
392 highlight: Some(Style::default().underlined()),
393 block: Some(Block::bordered()),
394 popup: PopupStyle::default(),
395 ..Default::default()
396 }
397 }
398
399 pub fn button_style(&self) -> ButtonStyle {
401 ButtonStyle {
402 style: self.button_base(),
403 focus: Some(self.focus()),
404 armed: Some(self.select()),
405 armed_delay: Some(Duration::from_millis(50)),
406 ..Default::default()
407 }
408 }
409
410 pub fn table_style(&self) -> TableStyle {
412 TableStyle {
413 style: self.container_base(),
414 select_row: Some(self.select()),
415 show_row_focus: true,
416 focus_style: Some(self.focus()),
417 border_style: Some(self.container_border()),
418 scroll: Some(self.scroll_style()),
419 ..Default::default()
420 }
421 }
422
423 pub fn table_header(&self) -> Style {
424 self.style(self.s.blue[2])
425 }
426
427 pub fn table_footer(&self) -> Style {
428 self.style(self.s.blue[2])
429 }
430
431 pub fn list_style(&self) -> ListStyle {
433 ListStyle {
434 style: self.container_base(),
435 select: Some(self.select()),
436 focus: Some(self.focus()),
437 scroll: Some(self.scroll_style()),
438 ..Default::default()
439 }
440 }
441
442 pub fn scroll_style(&self) -> ScrollStyle {
444 ScrollStyle {
445 thumb_style: Some(self.container_border()),
446 track_style: Some(self.container_border()),
447 min_style: Some(self.container_border()),
448 begin_style: Some(self.container_arrow()),
449 end_style: Some(self.container_arrow()),
450 ..Default::default()
451 }
452 }
453
454 pub fn popup_scroll_style(&self) -> ScrollStyle {
456 ScrollStyle {
457 thumb_style: Some(self.popup_border()),
458 track_style: Some(self.popup_border()),
459 min_style: Some(self.popup_border()),
460 begin_style: Some(self.popup_arrow()),
461 end_style: Some(self.popup_arrow()),
462 ..Default::default()
463 }
464 }
465
466 pub fn dialog_scroll_style(&self) -> ScrollStyle {
468 ScrollStyle {
469 thumb_style: Some(self.dialog_border()),
470 track_style: Some(self.dialog_border()),
471 min_style: Some(self.dialog_border()),
472 begin_style: Some(self.dialog_arrow()),
473 end_style: Some(self.dialog_arrow()),
474 ..Default::default()
475 }
476 }
477
478 pub fn split_style(&self) -> SplitStyle {
480 SplitStyle {
481 style: self.container_border(),
482 arrow_style: Some(self.container_arrow()),
483 drag_style: Some(self.focus()),
484 ..Default::default()
485 }
486 }
487
488 pub fn view_style(&self) -> ViewStyle {
490 ViewStyle {
491 scroll: Some(self.scroll_style()),
492 ..Default::default()
493 }
494 }
495
496 pub fn tabbed_style(&self) -> TabbedStyle {
498 TabbedStyle {
499 style: self.container_border(),
500 tab: Some(self.gray(1)),
501 select: Some(self.gray(3)),
502 focus: Some(self.focus()),
503 ..Default::default()
504 }
505 }
506
507 pub fn statusline_style(&self) -> Vec<Style> {
512 vec![
513 self.status_base(),
514 Style::default()
515 .fg(self.s.text_color(self.s.white[0]))
516 .bg(self.s.blue[3]),
517 Style::default()
518 .fg(self.s.text_color(self.s.white[0]))
519 .bg(self.s.blue[2]),
520 Style::default()
521 .fg(self.s.text_color(self.s.white[0]))
522 .bg(self.s.blue[1]),
523 ]
524 }
525
526 pub fn file_dialog_style(&self) -> FileDialogStyle {
528 FileDialogStyle {
529 style: self.dialog_base(),
530 list: Some(self.list_style()),
531 roots: Some(ListStyle {
532 style: self.dialog_base(),
533 ..self.list_style()
534 }),
535 text: Some(self.text_style()),
536 button: Some(self.button_style()),
537 block: Some(Block::bordered()),
538 ..Default::default()
539 }
540 }
541
542 pub fn msg_dialog_style(&self) -> MsgDialogStyle {
544 MsgDialogStyle {
545 style: self.dialog_base(),
546 button: Some(self.button_style()),
547 ..Default::default()
548 }
549 }
550
551 #[allow(deprecated)]
553 pub fn pager_style(&self) -> PagerStyle {
554 PagerStyle {
555 style: self.container_base(),
556 navigation: Some(self.container_arrow()),
557 block: Some(
558 Block::bordered()
559 .borders(Borders::TOP | Borders::BOTTOM)
560 .border_style(self.container_border()),
561 ),
562 ..Default::default()
563 }
564 }
565
566 pub fn clipper_style(&self) -> ClipperStyle {
568 ClipperStyle {
569 style: self.container_base(),
570 scroll: Some(self.scroll_style()),
571 ..Default::default()
572 }
573 }
574}