1use crate::menus::{Menu, MenuItem, MenuTheme};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct MenuBar {
9 pub menus: Vec<Menu>,
11
12 pub opened_menu: Option<usize>,
14
15 pub theme: MenuTheme,
17}
18
19impl Default for MenuBar {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl MenuBar {
27 pub fn new() -> Self {
29 Self {
30 menus: Vec::new(),
31 opened_menu: None,
32 theme: MenuTheme::default(),
33 }
34 }
35
36 pub fn from_menus<I, S>(menus: I) -> Self
56 where
57 I: IntoIterator<Item = (S, Option<char>, Vec<MenuItem>)>,
58 S: Into<String>,
59 {
60 let menus = menus
61 .into_iter()
62 .map(|(title, hotkey, items)| Menu::with_items(title, hotkey, items))
63 .collect();
64 Self {
65 menus,
66 opened_menu: None,
67 theme: MenuTheme::default(),
68 }
69 }
70
71 pub fn with_menus(menus: Vec<Menu>) -> Self {
84 Self {
85 menus,
86 opened_menu: None,
87 theme: MenuTheme::default(),
88 }
89 }
90
91 pub fn add_menu(&mut self, menu: Menu) -> &mut Self {
93 self.menus.push(menu);
94 self
95 }
96
97 pub fn set_theme(&mut self, theme: MenuTheme) -> &mut Self {
99 self.theme = theme;
100 self
101 }
102
103 pub fn theme(mut self, theme: MenuTheme) -> Self {
105 self.theme = theme;
106 self
107 }
108
109 pub fn get_theme(&self) -> &MenuTheme {
111 &self.theme
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn theme_switching_works() {
121 let mut menu_bar = MenuBar::new();
122
123 assert_eq!(menu_bar.get_theme(), &MenuTheme::classic());
125
126 menu_bar.set_theme(MenuTheme::dark());
128 assert_eq!(menu_bar.get_theme(), &MenuTheme::dark());
129
130 menu_bar.set_theme(MenuTheme::light());
132 assert_eq!(menu_bar.get_theme(), &MenuTheme::light());
133
134 menu_bar.set_theme(MenuTheme::terminal());
136 assert_eq!(menu_bar.get_theme(), &MenuTheme::terminal());
137 }
138
139 #[test]
140 fn theme_builder_pattern_works() {
141 let menu_bar = MenuBar::new().theme(MenuTheme::dark());
142 assert_eq!(menu_bar.get_theme(), &MenuTheme::dark());
143 }
144
145 #[test]
146 fn theme_switching_affects_rendering() {
147 use ratatui_core::{buffer::Buffer, layout::Rect, widgets::Widget};
148
149 let mut menu_bar = MenuBar::new();
150 let area = Rect::new(0, 0, 20, 1);
151
152 let mut buffer1 = Buffer::empty(area);
154 Widget::render(&menu_bar, area, &mut buffer1);
155 let classic_bg = buffer1[(0, 0)].bg;
156
157 menu_bar.set_theme(MenuTheme::dark());
159 let mut buffer2 = Buffer::empty(area);
160 Widget::render(&menu_bar, area, &mut buffer2);
161 let dark_bg = buffer2[(0, 0)].bg;
162
163 assert_ne!(classic_bg, dark_bg);
165 }
166}