145e17157SR0ronoa use std::{ 245e17157SR0ronoa any::Any, 345e17157SR0ronoa cell::{Cell, RefCell}, 445e17157SR0ronoa sync::Arc, 545e17157SR0ronoa }; 645e17157SR0ronoa 745e17157SR0ronoa use starry_client::base::renderer::Renderer; 8b0262857SR0ronoa use starry_server::core::{SCREEN_HEIGHT, SCREEN_WIDTH}; 945e17157SR0ronoa 101bee64b6SR0ronoa use crate::{ 111bee64b6SR0ronoa base::{event::Event, panel::Panel, rect::Rect, vector2::Vector2}, 121bee64b6SR0ronoa util::{align_rect, widget_set_panel}, 131bee64b6SR0ronoa }; 1445e17157SR0ronoa 1545e17157SR0ronoa pub mod image; 1645e17157SR0ronoa pub mod label; 1745e17157SR0ronoa 18*731cae06SR0ronoa /// 控件对齐类型 191bee64b6SR0ronoa #[derive(PartialEq, Copy, Clone, Debug)] 20b0262857SR0ronoa pub enum PivotType { 21b0262857SR0ronoa /// 不进行对齐 pivot_offset即为世界坐标 22b0262857SR0ronoa None, 23b0262857SR0ronoa /// 对齐左上角(默认对齐方式,这是由于矩形位置通过左上角顶点坐标来表示) 24b0262857SR0ronoa TopLeft, 25b0262857SR0ronoa /// 对齐正上方 26b0262857SR0ronoa Top, 27b0262857SR0ronoa /// 对齐右上角 28b0262857SR0ronoa TopRight, 29b0262857SR0ronoa /// 对齐正左方 3045e17157SR0ronoa Left, 31b0262857SR0ronoa /// 对齐中心 3245e17157SR0ronoa Center, 33b0262857SR0ronoa /// 对齐正右方 3445e17157SR0ronoa Right, 35b0262857SR0ronoa /// 对齐左下角 36b0262857SR0ronoa BottomLeft, 37b0262857SR0ronoa /// 对齐正下方 38b0262857SR0ronoa Bottom, 39b0262857SR0ronoa /// 对齐右下角 40b0262857SR0ronoa BottomRight, 4145e17157SR0ronoa } 4245e17157SR0ronoa 4345e17157SR0ronoa /// UI组件需要实现的特性 4445e17157SR0ronoa pub trait Widget: Any { 452b942a51SR0ronoa /// 返回自身指针 self_ref(&self) -> Arc<dyn Widget>462b942a51SR0ronoa fn self_ref(&self) -> Arc<dyn Widget>; 472b942a51SR0ronoa 481bee64b6SR0ronoa /// 返回Any引用 as_any_ref(&self) -> &dyn Any491bee64b6SR0ronoa fn as_any_ref(&self) -> &dyn Any; 501bee64b6SR0ronoa 5145e17157SR0ronoa /// 返回渲染的矩形区域 rect(&self) -> &Cell<Rect>5245e17157SR0ronoa fn rect(&self) -> &Cell<Rect>; 5345e17157SR0ronoa 54b0262857SR0ronoa /// 对齐方式 pivot(&self) -> &Cell<PivotType>55b0262857SR0ronoa fn pivot(&self) -> &Cell<PivotType>; 5645e17157SR0ronoa 57b0262857SR0ronoa /// 基于基准点的偏移量 pivot_offset(&self) -> &Cell<Vector2>58b0262857SR0ronoa fn pivot_offset(&self) -> &Cell<Vector2>; 5945e17157SR0ronoa 601bee64b6SR0ronoa /// 所属面板 panel(&self) -> &RefCell<Option<Arc<Panel>>>611bee64b6SR0ronoa fn panel(&self) -> &RefCell<Option<Arc<Panel>>>; 622b942a51SR0ronoa 6345e17157SR0ronoa /// 返回组件的名字 name(&self) -> &str6445e17157SR0ronoa fn name(&self) -> &str; 6545e17157SR0ronoa 6645e17157SR0ronoa /// 返回子组件数组 children(&self) -> &RefCell<Vec<Arc<dyn Widget>>>6745e17157SR0ronoa fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>>; 6845e17157SR0ronoa 692b942a51SR0ronoa /// 父物体 parent(&self) -> &RefCell<Option<Arc<dyn Widget>>>702b942a51SR0ronoa fn parent(&self) -> &RefCell<Option<Arc<dyn Widget>>>; 712b942a51SR0ronoa 722b942a51SR0ronoa /// 添加子物体 add_child(&self, widget: Arc<dyn Widget>)732b942a51SR0ronoa fn add_child(&self, widget: Arc<dyn Widget>) { 742b942a51SR0ronoa self.children().borrow_mut().push(widget.clone()); 751bee64b6SR0ronoa 761bee64b6SR0ronoa // 赋值父物体 772b942a51SR0ronoa (*widget.parent().borrow_mut()) = Some(self.self_ref()); 781bee64b6SR0ronoa 791bee64b6SR0ronoa // 赋值所属的面板 801bee64b6SR0ronoa if self.panel().borrow().is_some() { 811bee64b6SR0ronoa widget_set_panel(&widget, &self.panel().borrow().clone().unwrap()); 821bee64b6SR0ronoa } 832b942a51SR0ronoa } 842b942a51SR0ronoa 8545e17157SR0ronoa /// 渲染组件 draw(&self, renderer: &mut dyn Renderer, focused: bool)866f3c1837SR0ronoa fn draw(&self, renderer: &mut dyn Renderer, focused: bool); 8745e17157SR0ronoa 8845e17157SR0ronoa /// 更新组件状态 update(&self)8945e17157SR0ronoa fn update(&self) {} 9045e17157SR0ronoa 918a41b76cSR0ronoa /// 处理输入事件 handle_event( &self, _event: Event, _focused: bool, _redraw: &Cell<bool>, _caught: &Cell<bool>, ) -> bool928a41b76cSR0ronoa fn handle_event( 938a41b76cSR0ronoa &self, 948a41b76cSR0ronoa _event: Event, 958a41b76cSR0ronoa _focused: bool, 961bee64b6SR0ronoa _redraw: &Cell<bool>, 971bee64b6SR0ronoa _caught: &Cell<bool>, 988a41b76cSR0ronoa ) -> bool { 998a41b76cSR0ronoa false 1008a41b76cSR0ronoa } 1018a41b76cSR0ronoa set_pivot_type(&self, pivot_type: PivotType)102b0262857SR0ronoa fn set_pivot_type(&self, pivot_type: PivotType) { 103b0262857SR0ronoa self.set_pivot_type_base(pivot_type); 104b0262857SR0ronoa } 105b0262857SR0ronoa 106b0262857SR0ronoa /// 修改对齐方式的统一处理 方便覆写 set_pivot_type_base(&self, pivot_type: PivotType)107b0262857SR0ronoa fn set_pivot_type_base(&self, pivot_type: PivotType) { 108b0262857SR0ronoa self.pivot().set(pivot_type); 109b0262857SR0ronoa self.arrange_all(); 110b0262857SR0ronoa } 111b0262857SR0ronoa set_pivot_offset(&self, pivot_offset: Vector2)112b0262857SR0ronoa fn set_pivot_offset(&self, pivot_offset: Vector2) { 113b0262857SR0ronoa self.set_pivot_offset_base(pivot_offset); 114b0262857SR0ronoa } 115b0262857SR0ronoa 116b0262857SR0ronoa /// 修改对齐偏移量的统一处理 方便覆写 set_pivot_offset_base(&self, pivot_offset: Vector2)117b0262857SR0ronoa fn set_pivot_offset_base(&self, pivot_offset: Vector2) { 118b0262857SR0ronoa self.pivot_offset().set(pivot_offset); 119b0262857SR0ronoa self.arrange_all(); 120b0262857SR0ronoa } 121b0262857SR0ronoa resize(&self, width: u32, height: u32)122b0262857SR0ronoa fn resize(&self, width: u32, height: u32) { 123b0262857SR0ronoa self.resize_base(width, height); 124b0262857SR0ronoa } 125b0262857SR0ronoa 126b0262857SR0ronoa /// 修改大小时的统一处理 方便覆写 resize_base(&self, width: u32, height: u32)127b0262857SR0ronoa fn resize_base(&self, width: u32, height: u32) { 128b0262857SR0ronoa let mut rect = self.rect().get(); 129b0262857SR0ronoa rect.width = width; 130b0262857SR0ronoa rect.height = height; 131b0262857SR0ronoa self.rect().set(rect); 132b0262857SR0ronoa self.arrange_all(); 133b0262857SR0ronoa } 134b0262857SR0ronoa 135b0262857SR0ronoa /// 重新排布自身和子对象的位置 arrange_all(&self)136b0262857SR0ronoa fn arrange_all(&self) { 137b0262857SR0ronoa self.arrange_self(); 13849182ea7SR0ronoa 13949182ea7SR0ronoa for child in self.children().borrow_mut().iter() { 140b0262857SR0ronoa child.arrange_all(); 14149182ea7SR0ronoa } 14249182ea7SR0ronoa } 14349182ea7SR0ronoa arrange_self(&self)144b0262857SR0ronoa fn arrange_self(&self) { 145b0262857SR0ronoa self.arrange_self_base(); 14649182ea7SR0ronoa } 14749182ea7SR0ronoa 1482b942a51SR0ronoa /// 根据参考的矩形和pivot值来调整自身位置(默认为父物体,也可以自定义为其他矩形) 1492b942a51SR0ronoa /// 统一处理 方便覆写 arrange_self_base(&self)150b0262857SR0ronoa fn arrange_self_base(&self) { 151b0262857SR0ronoa let relative_rect: Rect = if self.parent().borrow().is_some() { 1522b942a51SR0ronoa // 优先以父物体作为参考 1532b942a51SR0ronoa self.parent().borrow().clone().unwrap().rect().get() 1541bee64b6SR0ronoa } else if self.panel().borrow().is_some() { 1552b942a51SR0ronoa // 没有父物体 则以所属面板作为参考 1561bee64b6SR0ronoa self.panel().borrow().clone().unwrap().rect() 157b0262857SR0ronoa } else { 1582b942a51SR0ronoa // 否则以整个屏幕作为参考 159b0262857SR0ronoa Rect::new(0, 0, SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32) 160b0262857SR0ronoa }; 161b0262857SR0ronoa 162b0262857SR0ronoa let target_rect = align_rect( 163b0262857SR0ronoa self.rect().get(), 164b0262857SR0ronoa relative_rect, 165b0262857SR0ronoa self.pivot().get(), 166b0262857SR0ronoa self.pivot_offset().get(), 167b0262857SR0ronoa ); 168b0262857SR0ronoa 169b0262857SR0ronoa self.rect().set(target_rect); 17049182ea7SR0ronoa } 17145e17157SR0ronoa } 172