1use ratatui::style::Color;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6pub enum ThemeName {
7 #[serde(rename = "dark")]
8 Dark,
9 #[serde(rename = "light")]
10 Light,
11 #[serde(rename = "midnight")]
12 Midnight,
13}
14
15impl Default for ThemeName {
16 fn default() -> Self {
17 ThemeName::Midnight
18 }
19}
20
21#[allow(dead_code)]
22impl ThemeName {
23 pub fn all() -> &'static [ThemeName] {
25 &[ThemeName::Dark, ThemeName::Light, ThemeName::Midnight]
26 }
27
28 pub fn next(&self) -> ThemeName {
30 match self {
31 ThemeName::Dark => ThemeName::Light,
32 ThemeName::Light => ThemeName::Midnight,
33 ThemeName::Midnight => ThemeName::Dark,
34 }
35 }
36
37 pub fn display_name(&self) -> &'static str {
39 match self {
40 ThemeName::Dark => "Dark",
41 ThemeName::Light => "Light",
42 ThemeName::Midnight => "Midnight(默认)",
43 }
44 }
45
46 pub fn from_str(s: &str) -> ThemeName {
48 match s.to_lowercase().as_str() {
49 "dark" => ThemeName::Dark,
50 "light" => ThemeName::Light,
51 "midnight" => ThemeName::Midnight,
52 _ => ThemeName::default(),
53 }
54 }
55
56 pub fn to_str(&self) -> &'static str {
58 match self {
59 ThemeName::Dark => "dark",
60 ThemeName::Light => "light",
61 ThemeName::Midnight => "midnight",
62 }
63 }
64}
65
66#[derive(Debug, Clone)]
69#[allow(dead_code)]
70pub struct Theme {
71 pub bg_primary: Color,
74 pub bg_title: Color,
76 pub bg_input: Color,
78 pub bg_panel: Color,
80
81 pub border_title: Color,
84 pub border_message: Color,
86 pub border_input: Color,
88 pub border_input_loading: Color,
90 pub border_config: Color,
92 pub separator: Color,
94
95 pub bubble_ai: Color,
98 pub bubble_ai_selected: Color,
100 pub bubble_user: Color,
102 pub bubble_user_selected: Color,
104
105 pub label_ai: Color,
108 pub label_user: Color,
110 pub label_selected: Color,
112
113 pub text_normal: Color,
116 pub text_bold: Color,
118 pub text_dim: Color,
120 pub text_very_dim: Color,
122 pub text_white: Color,
124 pub text_system: Color,
126
127 pub title_icon: Color,
130 pub title_separator: Color,
132 pub title_model: Color,
134 pub title_count: Color,
136 pub title_loading: Color,
138
139 pub input_prompt: Color,
142 pub input_prompt_loading: Color,
144 pub cursor_fg: Color,
146 pub cursor_bg: Color,
148
149 pub hint_key_fg: Color,
152 pub hint_key_bg: Color,
154 pub hint_desc: Color,
156 pub hint_separator: Color,
158
159 pub toast_success_border: Color,
162 pub toast_success_bg: Color,
164 pub toast_success_text: Color,
166 pub toast_error_border: Color,
168 pub toast_error_bg: Color,
170 pub toast_error_text: Color,
172
173 pub welcome_border: Color,
176 pub welcome_text: Color,
178 pub welcome_hint: Color,
180
181 pub model_sel_border: Color,
184 pub model_sel_title: Color,
186 pub model_sel_active: Color,
188 pub model_sel_inactive: Color,
190 pub model_sel_highlight_bg: Color,
192
193 pub config_title: Color,
196 pub config_section: Color,
198 pub config_pointer: Color,
200 pub config_label_selected: Color,
202 pub config_label: Color,
204 pub config_value: Color,
206 pub config_edit_bg: Color,
208 pub config_tab_active_bg: Color,
210 pub config_tab_active_fg: Color,
212 pub config_tab_inactive: Color,
214 pub config_hint_key: Color,
216 pub config_hint_desc: Color,
218 pub config_toggle_on: Color,
220 pub config_toggle_off: Color,
222 pub config_dim: Color,
224 pub config_api_key: Color,
226
227 pub md_h1: Color,
230 pub md_h2: Color,
232 pub md_h3: Color,
234 pub md_h4: Color,
236 pub md_heading_sep: Color,
238 pub md_inline_code_fg: Color,
240 pub md_inline_code_bg: Color,
242 pub md_list_bullet: Color,
244 pub md_blockquote_bar: Color,
246 pub md_blockquote_text: Color,
248 pub md_rule: Color,
250
251 pub code_border: Color,
254 pub code_bg: Color,
256 pub code_default: Color,
258 pub code_keyword: Color,
260 pub code_string: Color,
262 pub code_comment: Color,
264 pub code_number: Color,
266 pub code_type: Color,
268 pub code_primitive: Color,
270 pub code_macro: Color,
272 pub code_attribute: Color,
274 pub code_lifetime: Color,
276 pub code_shell_var: Color,
278
279 pub table_border: Color,
282 pub table_header: Color,
284 pub table_body: Color,
286
287 pub help_title: Color,
290 pub help_key: Color,
292 pub help_desc: Color,
294 pub help_path: Color,
296 pub help_bg: Color,
298}
299
300impl Theme {
301 pub fn from_name(name: &ThemeName) -> Self {
303 match name {
304 ThemeName::Dark => Self::dark(),
305 ThemeName::Light => Self::light(),
306 ThemeName::Midnight => Self::midnight(),
307 }
308 }
309
310 pub fn midnight() -> Self {
312 Self {
313 bg_primary: Color::Rgb(22, 22, 30),
315 bg_title: Color::Rgb(28, 28, 40),
316 bg_input: Color::Rgb(26, 26, 38),
317 bg_panel: Color::Rgb(24, 24, 34),
318
319 border_title: Color::Rgb(80, 100, 140),
321 border_message: Color::Rgb(50, 55, 70),
322 border_input: Color::Rgb(60, 100, 80),
323 border_input_loading: Color::Rgb(120, 100, 50),
324 border_config: Color::Rgb(80, 80, 110),
325 separator: Color::Rgb(50, 55, 70),
326
327 bubble_ai: Color::Rgb(38, 38, 52),
329 bubble_ai_selected: Color::Rgb(48, 48, 68),
330 bubble_user: Color::Rgb(40, 70, 120),
331 bubble_user_selected: Color::Rgb(55, 85, 140),
332
333 label_ai: Color::Rgb(120, 220, 160),
335 label_user: Color::Rgb(100, 160, 255),
336 label_selected: Color::Rgb(255, 200, 80),
337
338 text_normal: Color::Rgb(220, 220, 230),
340 text_bold: Color::Rgb(240, 210, 170),
341 text_dim: Color::Rgb(140, 140, 170),
342 text_very_dim: Color::Rgb(80, 80, 100),
343 text_white: Color::White,
344 text_system: Color::Rgb(100, 100, 120),
345
346 title_icon: Color::Rgb(120, 180, 255),
348 title_separator: Color::Rgb(60, 60, 80),
349 title_model: Color::Rgb(160, 220, 160),
350 title_count: Color::Rgb(180, 180, 200),
351 title_loading: Color::Rgb(255, 200, 80),
352
353 input_prompt: Color::Rgb(100, 200, 130),
355 input_prompt_loading: Color::Rgb(255, 200, 80),
356 cursor_fg: Color::Rgb(22, 22, 30),
357 cursor_bg: Color::Rgb(200, 210, 240),
358
359 hint_key_fg: Color::Rgb(22, 22, 30),
361 hint_key_bg: Color::Rgb(100, 110, 140),
362 hint_desc: Color::Rgb(120, 120, 150),
363 hint_separator: Color::Rgb(50, 50, 65),
364
365 toast_success_border: Color::Rgb(60, 160, 80),
367 toast_success_bg: Color::Rgb(18, 40, 25),
368 toast_success_text: Color::Rgb(140, 230, 160),
369 toast_error_border: Color::Rgb(200, 70, 70),
370 toast_error_bg: Color::Rgb(50, 18, 18),
371 toast_error_text: Color::Rgb(255, 130, 130),
372
373 welcome_border: Color::Rgb(60, 70, 90),
375 welcome_text: Color::Rgb(120, 140, 180),
376 welcome_hint: Color::Rgb(80, 90, 110),
377
378 model_sel_border: Color::Rgb(180, 160, 80),
380 model_sel_title: Color::Rgb(230, 210, 120),
381 model_sel_active: Color::Rgb(120, 220, 160),
382 model_sel_inactive: Color::Rgb(180, 180, 200),
383 model_sel_highlight_bg: Color::Rgb(50, 55, 80),
384
385 config_title: Color::Rgb(120, 180, 255),
387 config_section: Color::Rgb(160, 220, 160),
388 config_pointer: Color::Rgb(255, 200, 80),
389 config_label_selected: Color::Rgb(230, 210, 120),
390 config_label: Color::Rgb(140, 140, 160),
391 config_value: Color::Rgb(180, 180, 200),
392 config_edit_bg: Color::Rgb(50, 55, 80),
393 config_tab_active_bg: Color::Rgb(120, 180, 255),
394 config_tab_active_fg: Color::Rgb(22, 22, 30),
395 config_tab_inactive: Color::Rgb(150, 150, 170),
396 config_hint_key: Color::Rgb(230, 210, 120),
397 config_hint_desc: Color::Rgb(120, 120, 150),
398 config_toggle_on: Color::Rgb(120, 220, 160),
399 config_toggle_off: Color::Rgb(200, 100, 100),
400 config_dim: Color::Rgb(80, 80, 100),
401 config_api_key: Color::Rgb(100, 100, 120),
402
403 md_h1: Color::Rgb(100, 180, 255),
405 md_h2: Color::Rgb(130, 190, 255),
406 md_h3: Color::Rgb(160, 200, 255),
407 md_h4: Color::Rgb(180, 210, 255),
408 md_heading_sep: Color::Rgb(60, 70, 100),
409 md_inline_code_fg: Color::Rgb(230, 190, 120),
410 md_inline_code_bg: Color::Rgb(45, 45, 60),
411 md_list_bullet: Color::Rgb(100, 160, 255),
412 md_blockquote_bar: Color::Rgb(80, 100, 140),
413 md_blockquote_text: Color::Rgb(150, 160, 180),
414 md_rule: Color::Rgb(70, 75, 90),
415
416 code_border: Color::Rgb(80, 90, 110),
418 code_bg: Color::Rgb(30, 30, 42),
419 code_default: Color::Rgb(171, 178, 191),
420 code_keyword: Color::Rgb(198, 120, 221),
421 code_string: Color::Rgb(152, 195, 121),
422 code_comment: Color::Rgb(92, 99, 112),
423 code_number: Color::Rgb(209, 154, 102),
424 code_type: Color::Rgb(229, 192, 123),
425 code_primitive: Color::Rgb(86, 182, 194),
426 code_macro: Color::Rgb(97, 175, 239),
427 code_attribute: Color::Rgb(86, 182, 194),
428 code_lifetime: Color::Rgb(229, 192, 123),
429 code_shell_var: Color::Rgb(86, 182, 194),
430
431 table_border: Color::Rgb(60, 70, 100),
433 table_header: Color::Rgb(120, 180, 255),
434 table_body: Color::Rgb(180, 180, 200),
435
436 help_title: Color::Rgb(120, 180, 255),
438 help_key: Color::Rgb(230, 210, 120),
439 help_desc: Color::Rgb(200, 200, 220),
440 help_path: Color::Rgb(100, 100, 130),
441 help_bg: Color::Rgb(24, 24, 34),
442 }
443 }
444
445 pub fn dark() -> Self {
447 Self {
448 bg_primary: Color::Rgb(30, 30, 30),
450 bg_title: Color::Rgb(37, 37, 38),
451 bg_input: Color::Rgb(37, 37, 38),
452 bg_panel: Color::Rgb(37, 37, 38),
453
454 border_title: Color::Rgb(70, 70, 70),
456 border_message: Color::Rgb(55, 55, 55),
457 border_input: Color::Rgb(55, 80, 55),
458 border_input_loading: Color::Rgb(120, 100, 50),
459 border_config: Color::Rgb(70, 70, 70),
460 separator: Color::Rgb(55, 55, 55),
461
462 bubble_ai: Color::Rgb(40, 40, 40),
464 bubble_ai_selected: Color::Rgb(50, 50, 55),
465 bubble_user: Color::Rgb(38, 65, 110),
466 bubble_user_selected: Color::Rgb(50, 80, 130),
467
468 label_ai: Color::Rgb(80, 200, 120),
470 label_user: Color::Rgb(80, 150, 240),
471 label_selected: Color::Rgb(255, 200, 80),
472
473 text_normal: Color::Rgb(212, 212, 212),
475 text_bold: Color::Rgb(230, 200, 160),
476 text_dim: Color::Rgb(128, 128, 128),
477 text_very_dim: Color::Rgb(80, 80, 80),
478 text_white: Color::White,
479 text_system: Color::Rgb(100, 100, 100),
480
481 title_icon: Color::Rgb(100, 160, 240),
483 title_separator: Color::Rgb(60, 60, 60),
484 title_model: Color::Rgb(140, 200, 140),
485 title_count: Color::Rgb(170, 170, 170),
486 title_loading: Color::Rgb(255, 200, 80),
487
488 input_prompt: Color::Rgb(80, 180, 100),
490 input_prompt_loading: Color::Rgb(255, 200, 80),
491 cursor_fg: Color::Rgb(30, 30, 30),
492 cursor_bg: Color::Rgb(200, 200, 200),
493
494 hint_key_fg: Color::Rgb(30, 30, 30),
496 hint_key_bg: Color::Rgb(100, 100, 100),
497 hint_desc: Color::Rgb(128, 128, 128),
498 hint_separator: Color::Rgb(50, 50, 50),
499
500 toast_success_border: Color::Rgb(60, 160, 80),
502 toast_success_bg: Color::Rgb(20, 40, 25),
503 toast_success_text: Color::Rgb(140, 230, 160),
504 toast_error_border: Color::Rgb(200, 70, 70),
505 toast_error_bg: Color::Rgb(50, 20, 20),
506 toast_error_text: Color::Rgb(255, 130, 130),
507
508 welcome_border: Color::Rgb(60, 60, 60),
510 welcome_text: Color::Rgb(120, 140, 180),
511 welcome_hint: Color::Rgb(80, 80, 80),
512
513 model_sel_border: Color::Rgb(180, 160, 80),
515 model_sel_title: Color::Rgb(230, 210, 120),
516 model_sel_active: Color::Rgb(80, 200, 120),
517 model_sel_inactive: Color::Rgb(170, 170, 170),
518 model_sel_highlight_bg: Color::Rgb(50, 50, 60),
519
520 config_title: Color::Rgb(100, 160, 240),
522 config_section: Color::Rgb(140, 200, 140),
523 config_pointer: Color::Rgb(255, 200, 80),
524 config_label_selected: Color::Rgb(230, 210, 120),
525 config_label: Color::Rgb(128, 128, 128),
526 config_value: Color::Rgb(170, 170, 170),
527 config_edit_bg: Color::Rgb(50, 50, 60),
528 config_tab_active_bg: Color::Rgb(100, 160, 240),
529 config_tab_active_fg: Color::Rgb(30, 30, 30),
530 config_tab_inactive: Color::Rgb(140, 140, 140),
531 config_hint_key: Color::Rgb(230, 210, 120),
532 config_hint_desc: Color::Rgb(128, 128, 128),
533 config_toggle_on: Color::Rgb(80, 200, 120),
534 config_toggle_off: Color::Rgb(200, 100, 100),
535 config_dim: Color::Rgb(80, 80, 80),
536 config_api_key: Color::Rgb(100, 100, 100),
537
538 md_h1: Color::Rgb(80, 160, 240),
540 md_h2: Color::Rgb(100, 170, 240),
541 md_h3: Color::Rgb(120, 180, 240),
542 md_h4: Color::Rgb(140, 190, 240),
543 md_heading_sep: Color::Rgb(60, 60, 80),
544 md_inline_code_fg: Color::Rgb(220, 180, 110),
545 md_inline_code_bg: Color::Rgb(50, 50, 60),
546 md_list_bullet: Color::Rgb(80, 150, 240),
547 md_blockquote_bar: Color::Rgb(70, 90, 130),
548 md_blockquote_text: Color::Rgb(150, 150, 170),
549 md_rule: Color::Rgb(70, 70, 80),
550
551 code_border: Color::Rgb(70, 70, 80),
553 code_bg: Color::Rgb(35, 35, 38),
554 code_default: Color::Rgb(212, 212, 212),
555 code_keyword: Color::Rgb(198, 120, 221),
556 code_string: Color::Rgb(152, 195, 121),
557 code_comment: Color::Rgb(106, 115, 125),
558 code_number: Color::Rgb(209, 154, 102),
559 code_type: Color::Rgb(229, 192, 123),
560 code_primitive: Color::Rgb(86, 182, 194),
561 code_macro: Color::Rgb(97, 175, 239),
562 code_attribute: Color::Rgb(86, 182, 194),
563 code_lifetime: Color::Rgb(229, 192, 123),
564 code_shell_var: Color::Rgb(86, 182, 194),
565
566 table_border: Color::Rgb(60, 60, 80),
568 table_header: Color::Rgb(80, 160, 240),
569 table_body: Color::Rgb(170, 170, 170),
570
571 help_title: Color::Rgb(100, 160, 240),
573 help_key: Color::Rgb(230, 210, 120),
574 help_desc: Color::Rgb(200, 200, 200),
575 help_path: Color::Rgb(100, 100, 100),
576 help_bg: Color::Rgb(37, 37, 38),
577 }
578 }
579
580 pub fn light() -> Self {
582 Self {
583 bg_primary: Color::Rgb(255, 255, 255),
585 bg_title: Color::Rgb(243, 243, 243),
586 bg_input: Color::Rgb(248, 248, 248),
587 bg_panel: Color::Rgb(248, 248, 248),
588
589 border_title: Color::Rgb(190, 190, 200),
591 border_message: Color::Rgb(210, 210, 220),
592 border_input: Color::Rgb(160, 200, 160),
593 border_input_loading: Color::Rgb(180, 150, 50),
594 border_config: Color::Rgb(190, 190, 200),
595 separator: Color::Rgb(210, 210, 220),
596
597 bubble_ai: Color::Rgb(240, 240, 245),
599 bubble_ai_selected: Color::Rgb(225, 230, 240),
600 bubble_user: Color::Rgb(210, 230, 255),
601 bubble_user_selected: Color::Rgb(190, 215, 250),
602
603 label_ai: Color::Rgb(40, 140, 80),
605 label_user: Color::Rgb(30, 100, 200),
606 label_selected: Color::Rgb(180, 130, 20),
607
608 text_normal: Color::Rgb(40, 40, 50),
610 text_bold: Color::Rgb(150, 90, 30),
611 text_dim: Color::Rgb(120, 120, 140),
612 text_very_dim: Color::Rgb(170, 170, 180),
613 text_white: Color::Rgb(40, 40, 50),
614 text_system: Color::Rgb(140, 140, 160),
615
616 title_icon: Color::Rgb(40, 100, 200),
618 title_separator: Color::Rgb(200, 200, 210),
619 title_model: Color::Rgb(40, 140, 80),
620 title_count: Color::Rgb(100, 100, 120),
621 title_loading: Color::Rgb(180, 130, 20),
622
623 input_prompt: Color::Rgb(40, 140, 80),
625 input_prompt_loading: Color::Rgb(180, 130, 20),
626 cursor_fg: Color::Rgb(255, 255, 255),
627 cursor_bg: Color::Rgb(50, 100, 200),
628
629 hint_key_fg: Color::Rgb(255, 255, 255),
631 hint_key_bg: Color::Rgb(100, 110, 130),
632 hint_desc: Color::Rgb(120, 120, 140),
633 hint_separator: Color::Rgb(210, 210, 220),
634
635 toast_success_border: Color::Rgb(60, 160, 80),
637 toast_success_bg: Color::Rgb(230, 250, 235),
638 toast_success_text: Color::Rgb(30, 100, 50),
639 toast_error_border: Color::Rgb(200, 70, 70),
640 toast_error_bg: Color::Rgb(255, 235, 235),
641 toast_error_text: Color::Rgb(160, 30, 30),
642
643 welcome_border: Color::Rgb(180, 190, 210),
645 welcome_text: Color::Rgb(60, 80, 130),
646 welcome_hint: Color::Rgb(140, 150, 170),
647
648 model_sel_border: Color::Rgb(180, 160, 80),
650 model_sel_title: Color::Rgb(140, 110, 30),
651 model_sel_active: Color::Rgb(40, 140, 80),
652 model_sel_inactive: Color::Rgb(100, 100, 120),
653 model_sel_highlight_bg: Color::Rgb(225, 230, 245),
654
655 config_title: Color::Rgb(40, 100, 200),
657 config_section: Color::Rgb(40, 140, 80),
658 config_pointer: Color::Rgb(180, 130, 20),
659 config_label_selected: Color::Rgb(140, 110, 30),
660 config_label: Color::Rgb(120, 120, 140),
661 config_value: Color::Rgb(60, 60, 80),
662 config_edit_bg: Color::Rgb(225, 230, 245),
663 config_tab_active_bg: Color::Rgb(40, 100, 200),
664 config_tab_active_fg: Color::Rgb(255, 255, 255),
665 config_tab_inactive: Color::Rgb(120, 120, 140),
666 config_hint_key: Color::Rgb(140, 110, 30),
667 config_hint_desc: Color::Rgb(120, 120, 140),
668 config_toggle_on: Color::Rgb(40, 140, 80),
669 config_toggle_off: Color::Rgb(200, 80, 80),
670 config_dim: Color::Rgb(170, 170, 180),
671 config_api_key: Color::Rgb(160, 160, 170),
672
673 md_h1: Color::Rgb(30, 80, 180),
675 md_h2: Color::Rgb(40, 100, 200),
676 md_h3: Color::Rgb(50, 110, 210),
677 md_h4: Color::Rgb(60, 120, 220),
678 md_heading_sep: Color::Rgb(180, 190, 210),
679 md_inline_code_fg: Color::Rgb(160, 80, 30),
680 md_inline_code_bg: Color::Rgb(240, 235, 225),
681 md_list_bullet: Color::Rgb(30, 100, 200),
682 md_blockquote_bar: Color::Rgb(100, 130, 180),
683 md_blockquote_text: Color::Rgb(80, 90, 110),
684 md_rule: Color::Rgb(190, 195, 210),
685
686 code_border: Color::Rgb(190, 195, 210),
688 code_bg: Color::Rgb(245, 245, 248),
689 code_default: Color::Rgb(40, 40, 50),
690 code_keyword: Color::Rgb(175, 0, 219),
691 code_string: Color::Rgb(163, 21, 21),
692 code_comment: Color::Rgb(0, 128, 0),
693 code_number: Color::Rgb(9, 134, 88),
694 code_type: Color::Rgb(38, 127, 153),
695 code_primitive: Color::Rgb(0, 112, 193),
696 code_macro: Color::Rgb(121, 94, 38),
697 code_attribute: Color::Rgb(0, 112, 193),
698 code_lifetime: Color::Rgb(38, 127, 153),
699 code_shell_var: Color::Rgb(0, 112, 193),
700
701 table_border: Color::Rgb(180, 190, 210),
703 table_header: Color::Rgb(30, 80, 180),
704 table_body: Color::Rgb(60, 60, 80),
705
706 help_title: Color::Rgb(40, 100, 200),
708 help_key: Color::Rgb(140, 110, 30),
709 help_desc: Color::Rgb(50, 50, 60),
710 help_path: Color::Rgb(120, 120, 140),
711 help_bg: Color::Rgb(248, 248, 248),
712 }
713 }
714}