grid.rs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. use std::{
  2. cell::{Cell, RefCell},
  3. collections::BTreeMap,
  4. sync::Arc,
  5. };
  6. use starry_client::base::renderer::Renderer;
  7. use crate::{
  8. base::{event::Event, rect::Rect, vector2::Vector2},
  9. traits::{enter::Enter, focus::Focus},
  10. widgets::{PivotType, Widget},
  11. };
  12. /// 网格排列方式
  13. #[derive(PartialEq, Copy, Clone)]
  14. pub enum GridArrangeType {
  15. /// 优先横向排列
  16. Horizontal,
  17. /// 优先纵向排列
  18. Vertical,
  19. }
  20. pub struct Grid {
  21. pub rect: Cell<Rect>,
  22. pivot: Cell<PivotType>,
  23. pivot_offset: Cell<Vector2>,
  24. children: RefCell<Vec<Arc<dyn Widget>>>,
  25. parent: RefCell<Option<Arc<dyn Widget>>>,
  26. /// x坐标间隔
  27. space_x: Cell<i32>,
  28. /// y坐标间隔
  29. space_y: Cell<i32>,
  30. /// 每行/列的最大元素数
  31. upper_limit: Cell<usize>,
  32. /// 当前行数
  33. pub current_row: Cell<usize>,
  34. /// 当前列数
  35. pub current_column: Cell<usize>,
  36. /// 当前最大行数
  37. pub max_row: Cell<usize>,
  38. /// 当前最大列数
  39. pub max_column: Cell<usize>,
  40. /// 元素字典
  41. pub elements: RefCell<BTreeMap<(usize, usize), Arc<dyn Widget>>>,
  42. /// 当前选中的元素id(行列号)
  43. pub focused_id: Cell<Option<(usize, usize)>>,
  44. /// 当前聚焦的widget
  45. pub focused_widget: RefCell<Option<Arc<dyn Widget>>>,
  46. /// 优先排列方式
  47. arrange_type: Cell<GridArrangeType>,
  48. /// 键盘输入回调
  49. enter_callback: RefCell<Option<Arc<dyn Fn(&Self, char, &mut bool)>>>,
  50. }
  51. impl Grid {
  52. pub fn new() -> Arc<Self> {
  53. Arc::new(Grid {
  54. rect: Cell::new(Rect::default()),
  55. pivot: Cell::new(PivotType::TopLeft),
  56. pivot_offset: Cell::new(Vector2::new(0, 0)),
  57. children: RefCell::new(vec![]),
  58. parent: RefCell::new(None),
  59. space_x: Cell::new(0),
  60. space_y: Cell::new(0),
  61. upper_limit: Cell::new(0),
  62. current_row: Cell::new(0),
  63. current_column: Cell::new(0),
  64. max_row: Cell::new(0),
  65. max_column: Cell::new(0),
  66. elements: RefCell::new(BTreeMap::new()),
  67. focused_id: Cell::new(None),
  68. focused_widget: RefCell::new(None),
  69. arrange_type: Cell::new(GridArrangeType::Vertical),
  70. enter_callback: RefCell::new(None),
  71. })
  72. }
  73. /// 设置每行/列最大元素数量(取决于行/列优先排列)
  74. pub fn set_upper_limit(&self, columns: usize) -> &Self {
  75. self.upper_limit.set(columns);
  76. self
  77. }
  78. pub fn set_arrange_type(&self, arrange_type: GridArrangeType) -> &Self {
  79. self.arrange_type.set(arrange_type);
  80. self
  81. }
  82. pub fn add<T: Widget>(&self, element: &Arc<T>) -> (usize, usize) {
  83. self.find_next_slot();
  84. self.elements.borrow_mut().insert(
  85. (self.current_row.get(), self.current_column.get()),
  86. element.clone(),
  87. );
  88. let res = (self.current_row.get(), self.current_column.get());
  89. self.move_index();
  90. self.arrange_elements(false);
  91. return res;
  92. }
  93. /// 找到下一个可放置元素的位置
  94. fn find_next_slot(&self) {
  95. let elements = self.elements.borrow();
  96. while elements.contains_key(&(self.current_row.get(), self.current_column.get())) {
  97. self.move_index();
  98. }
  99. }
  100. fn move_index(&self) {
  101. match self.arrange_type.get() {
  102. GridArrangeType::Horizontal => {
  103. self.current_column.set(self.current_column.get() + 1);
  104. if self.current_column.get() == self.upper_limit.get() {
  105. self.current_row.set(self.current_row.get() + 1);
  106. self.current_column.set(0);
  107. }
  108. }
  109. GridArrangeType::Vertical => {
  110. self.current_row.set(self.current_row.get() + 1);
  111. if self.current_row.get() == self.upper_limit.get() {
  112. self.current_column.set(self.current_column.get() + 1);
  113. self.current_row.set(0);
  114. }
  115. }
  116. }
  117. }
  118. pub fn insert<T: Widget>(&self, column: usize, row: usize, element: &Arc<T>) {
  119. self.elements
  120. .borrow_mut()
  121. .insert((row, column), element.clone());
  122. self.arrange_elements(false);
  123. }
  124. pub fn remove(&self, column: usize, row: usize) {
  125. self.elements.borrow_mut().remove(&(row, column));
  126. }
  127. pub fn set_space(&self, x: i32, y: i32) -> &Self {
  128. self.space_x.set(x);
  129. self.space_y.set(y);
  130. self
  131. }
  132. // TODO 注释补充
  133. pub fn arrange_elements(&self, resize_children: bool) {
  134. if self.elements.borrow().is_empty() {
  135. return;
  136. }
  137. self.arrange_self();
  138. let mut cols = Vec::new();
  139. let mut rows = Vec::new();
  140. for (&(row, col), entry) in self.elements.borrow().iter() {
  141. while col >= cols.len() {
  142. cols.push(Rect::default());
  143. }
  144. while row >= rows.len() {
  145. rows.push(Rect::default());
  146. }
  147. let rect = entry.rect().get();
  148. if rect.width >= cols[col].width {
  149. cols[col as usize].width = rect.width;
  150. }
  151. if rect.width >= rows[row].width {
  152. rows[row as usize].width = rect.width;
  153. }
  154. if rect.height >= cols[col].height {
  155. cols[col as usize].height = rect.height;
  156. }
  157. if rect.height >= rows[row].height {
  158. rows[row as usize].height = rect.height;
  159. }
  160. }
  161. self.max_row.set(rows.len());
  162. self.max_column.set(cols.len());
  163. let space_x = self.space_x.get();
  164. let space_y = self.space_y.get();
  165. let mut x = 0;
  166. for col in cols.iter_mut() {
  167. col.x = x;
  168. x += col.width as i32 + space_x;
  169. }
  170. let mut y = 0;
  171. for row in rows.iter_mut() {
  172. row.y = y;
  173. y += row.height as i32 + space_y;
  174. }
  175. let grid_width = cols.len() as i32 * (cols[0].width as i32 + space_x) - space_x;
  176. let grid_height = rows.len() as i32 * (rows[0].width as i32 + space_y) - space_y;
  177. self.resize(grid_width as u32, grid_height as u32);
  178. for (&(row, col), child) in self.elements.borrow().iter() {
  179. child.set_pivot_type(PivotType::TopLeft);
  180. child.set_pivot_offset(Vector2::new(cols[col].x, rows[row].y));
  181. if resize_children {
  182. child.resize(cols[col].width, rows[row].height);
  183. }
  184. child.arrange_all();
  185. }
  186. }
  187. pub fn clear(&self) {
  188. self.children.borrow_mut().clear();
  189. self.elements.borrow_mut().clear();
  190. self.current_column.set(0);
  191. self.current_row.set(0);
  192. }
  193. }
  194. impl Widget for Grid {
  195. fn name(&self) -> &str {
  196. "Grid"
  197. }
  198. fn rect(&self) -> &Cell<Rect> {
  199. &self.rect
  200. }
  201. fn pivot(&self) -> &Cell<PivotType> {
  202. &self.pivot
  203. }
  204. fn pivot_offset(&self) -> &Cell<Vector2> {
  205. &self.pivot_offset
  206. }
  207. fn parent(&self) -> &RefCell<Option<Arc<dyn Widget>>> {
  208. &self.parent
  209. }
  210. fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> {
  211. &self.children
  212. }
  213. fn draw(&self, renderer: &mut dyn Renderer, _focused: bool) {
  214. for (&(_row, _col), widget) in self.elements.borrow().iter() {
  215. widget.update();
  216. widget.draw(renderer, self.is_focused(widget));
  217. }
  218. }
  219. fn handle_event(
  220. &self,
  221. event: Event,
  222. _focused: bool,
  223. redraw: &mut bool,
  224. caught: &mut bool,
  225. ) -> bool {
  226. match event {
  227. Event::KeyPressed { character, .. } => {
  228. if let Some(character) = character {
  229. self.emit_enter(character, redraw);
  230. }
  231. *caught = true;
  232. }
  233. // TODO
  234. _ => {}
  235. }
  236. false
  237. }
  238. }
  239. impl Focus for Grid {
  240. fn focused_widget(&self) -> RefCell<Option<Arc<dyn Widget>>> {
  241. self.focused_widget.clone()
  242. }
  243. fn focus(&self, widget: &Arc<dyn Widget>) {
  244. (*self.focused_widget.borrow_mut()) = Some(widget.clone());
  245. }
  246. }
  247. impl Enter for Grid {
  248. fn emit_enter(&self, char: char, redraw: &mut bool) {
  249. if let Some(ref enter_callback) = *self.enter_callback.borrow() {
  250. enter_callback(self, char, redraw);
  251. }
  252. }
  253. fn set_enter_callback<T: Fn(&Self, char, &mut bool) + 'static>(&self, func: T) {
  254. (*self.enter_callback.borrow_mut()) = Some(Arc::new(func));
  255. }
  256. }