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