1 use std::{ 2 cell::{Cell, RefCell}, 3 collections::BTreeMap, 4 sync::Arc, 5 }; 6 7 use starry_client::base::renderer::Renderer; 8 9 use crate::{ 10 base::{point::Point, rect::Rect}, 11 traits::{focus::Focus, transform::Transform}, 12 widgets::{HorizontalPlacement, VerticalPlacement, Widget}, 13 }; 14 15 pub struct Grid { 16 pub rect: Cell<Rect>, 17 local_position: Cell<Point>, 18 vertical_placement: Cell<VerticalPlacement>, 19 horizontal_placement: Cell<HorizontalPlacement>, 20 children: RefCell<Vec<Arc<dyn Widget>>>, 21 /// x坐标间隔 22 space_x: Cell<i32>, 23 /// y坐标间隔 24 space_y: Cell<i32>, 25 /// 每行的最大列数 26 max_columns: Cell<usize>, 27 /// 当前行数 28 current_row: Cell<usize>, 29 /// 当前列数 30 current_column: Cell<usize>, 31 /// 元素字典 32 pub elements: RefCell<BTreeMap<(usize, usize), Arc<dyn Widget>>>, 33 /// 当前选中的元素id(行列号) 34 pub focused_id: Cell<Option<(usize, usize)>>, 35 /// 当前聚焦的widget 36 pub focused_widget: RefCell<Option<Arc<dyn Widget>>>, 37 } 38 39 impl Grid { 40 pub fn new() -> Arc<Self> { 41 Arc::new(Grid { 42 rect: Cell::new(Rect::default()), 43 local_position: Cell::new(Point::new(0, 0)), 44 vertical_placement: Cell::new(VerticalPlacement::Absolute), 45 horizontal_placement: Cell::new(HorizontalPlacement::Absolute), 46 children: RefCell::new(vec![]), 47 space_x: Cell::new(0), 48 space_y: Cell::new(0), 49 max_columns: Cell::new(0), 50 current_row: Cell::new(0), 51 current_column: Cell::new(0), 52 elements: RefCell::new(BTreeMap::new()), 53 focused_id: Cell::new(None), 54 focused_widget: RefCell::new(None), 55 }) 56 } 57 58 /// 设置最大列数 59 pub fn set_max_columns(&self, columns: usize) -> &Self { 60 self.max_columns.set(columns); 61 self 62 } 63 64 pub fn add<T: Widget>(&self, element: &Arc<T>) { 65 if self.current_column.get() == self.max_columns.get() { 66 self.current_row.set(self.current_row.get() + 1); 67 self.current_column.set(0); 68 } 69 70 self.elements.borrow_mut().insert( 71 (self.current_row.get(), self.current_column.get()), 72 element.clone(), 73 ); 74 self.current_column.set(self.current_column.get() + 1); 75 self.arrange(false); 76 } 77 78 pub fn insert<T: Widget>(&self, column: usize, row: usize, element: &Arc<T>) { 79 self.elements 80 .borrow_mut() 81 .insert((row, column), element.clone()); 82 83 self.arrange(false); 84 } 85 86 pub fn clear(&self) { 87 self.elements.borrow_mut().clear(); 88 } 89 90 pub fn remove(&self, column: usize, row: usize) { 91 self.elements.borrow_mut().remove(&(row, column)); 92 } 93 94 pub fn set_space(&self, x: i32, y: i32) -> &Self { 95 self.space_x.set(x); 96 self.space_y.set(y); 97 self 98 } 99 100 pub fn arrange(&self, resize_children: bool) { 101 let mut cols = Vec::new(); 102 let mut rows = Vec::new(); 103 for (&(col, row), entry) in self.elements.borrow().iter() { 104 while col >= cols.len() { 105 cols.push(Rect::default()); 106 } 107 while row >= rows.len() { 108 rows.push(Rect::default()); 109 } 110 let rect = entry.rect().get(); 111 if rect.width >= cols[col].width { 112 cols[col as usize].width = rect.width; 113 } 114 if rect.width >= rows[row].width { 115 rows[row as usize].width = rect.width; 116 } 117 if rect.height >= cols[col].height { 118 cols[col as usize].height = rect.height; 119 } 120 if rect.height >= rows[row].height { 121 rows[row as usize].height = rect.height; 122 } 123 } 124 125 let rect = self.rect.get(); 126 let space_x = self.space_x.get(); 127 let space_y = self.space_y.get(); 128 129 let mut x = rect.x; 130 for col in cols.iter_mut() { 131 col.x = x; 132 x += col.width as i32 + space_x; 133 } 134 135 let mut y = rect.y; 136 for row in rows.iter_mut() { 137 row.y = y; 138 y += row.height as i32 + space_y; 139 } 140 141 for (&(col, row), child) in self.elements.borrow().iter() { 142 let mut rect = child.rect().get(); 143 rect.x = cols[col].x; 144 rect.y = rows[row].y; 145 if resize_children { 146 rect.width = cols[col].width; 147 rect.height = rows[row].height; 148 } 149 child.rect().set(rect); 150 151 child.arrange(); 152 } 153 } 154 } 155 156 impl Widget for Grid { 157 fn name(&self) -> &str { 158 "Grid" 159 } 160 161 fn rect(&self) -> &Cell<Rect> { 162 &self.rect 163 } 164 165 fn local_position(&self) -> &Cell<Point> { 166 &self.local_position 167 } 168 169 fn vertical_placement(&self) -> &Cell<VerticalPlacement> { 170 &self.vertical_placement 171 } 172 173 fn horizontal_placement(&self) -> &Cell<HorizontalPlacement> { 174 &self.horizontal_placement 175 } 176 177 fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> { 178 &self.children 179 } 180 181 fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) { 182 fn draw_widget(widget: &Arc<dyn Widget>, renderer: &mut dyn Renderer, focused: bool) { 183 widget.update(); 184 widget.draw(renderer, focused); 185 186 for child in widget.children().borrow().iter() { 187 draw_widget(child, renderer, focused); 188 } 189 } 190 191 for (&(_col, _row), widget) in self.elements.borrow().iter() { 192 draw_widget(widget, renderer, self.is_focused(widget)); 193 } 194 } 195 } 196 197 impl Transform for Grid { 198 fn reposition(&self, x: i32, y: i32) -> &Self { 199 let mut rect = self.rect().get(); 200 rect.x = x; 201 rect.y = y; 202 self.rect.set(rect); 203 204 self.arrange(false); 205 206 self 207 } 208 } 209 210 impl Focus for Grid { 211 fn focused_widget(&self) -> RefCell<Option<Arc<dyn Widget>>> { 212 self.focused_widget.clone() 213 } 214 215 fn focus(&self, widget: &Arc<dyn Widget>) { 216 (*self.focused_widget.borrow_mut()) = Some(widget.clone()); 217 } 218 } 219