1 use std::{ 2 cell::{Cell, RefCell}, 3 sync::Arc, 4 }; 5 6 use starry_client::{ 7 base::{ 8 color::Color, 9 renderer::{RenderMode, Renderer}, 10 }, 11 window::Window, 12 }; 13 14 use crate::widgets::Widget; 15 16 use super::rect::Rect; 17 18 /// 面板渲染器 19 pub struct PanelRenderer<'a> { 20 /// 客户端窗口 21 window: &'a mut Window, 22 } 23 24 impl<'a> PanelRenderer<'a> { 25 pub fn new(window: &'a mut Window) -> Self { 26 PanelRenderer { window } 27 } 28 } 29 30 impl<'a> Renderer for PanelRenderer<'a> { 31 fn width(&self) -> u32 { 32 self.window.width() 33 } 34 35 fn height(&self) -> u32 { 36 self.window.height() 37 } 38 39 fn data(&self) -> &[Color] { 40 self.window.data() 41 } 42 43 fn data_mut(&mut self) -> &mut [Color] { 44 self.window.data_mut() 45 } 46 47 fn sync(&mut self) -> bool { 48 self.window.sync() 49 } 50 51 fn mode(&self) -> &Cell<RenderMode> { 52 &self.window.mode() 53 } 54 55 // TODO 56 // fn char(&mut self, x: i32, y: i32, c: char, color: Color) { 57 // } 58 } 59 60 impl<'a> Drop for PanelRenderer<'a> { 61 fn drop(&mut self) { 62 self.window.sync(); 63 } 64 } 65 66 /// UI面板类作为容器管理一组UI组件(UI-Widget) 67 /// 拥有一个窗口对象用于渲染和事件传递 68 pub struct Panel { 69 /// 客户端窗口对象 70 window: RefCell<Window>, 71 /// 子组件数组 72 pub widgets: RefCell<Vec<Arc<dyn Widget>>>, 73 /// 窗口是否打开 74 pub running: Cell<bool>, 75 } 76 77 impl Panel { 78 pub fn new(rect: Rect, title: &str) -> Self { 79 Panel::from_window(Window::new(rect.x, rect.y, rect.width, rect.height, title)) 80 } 81 82 pub fn from_window(window: Window) -> Self { 83 Panel { 84 window: RefCell::new(window), 85 widgets: RefCell::new(Vec::new()), 86 running: Cell::new(true), 87 } 88 } 89 90 /// 获得客户端窗口对象 91 pub fn into_window(self) -> Window { 92 self.window.into_inner() 93 } 94 95 /// 返回x坐标 96 pub fn x(&self) -> i32 { 97 let window = self.window.borrow(); 98 (*window).x() 99 } 100 101 /// 返回y坐标 102 pub fn y(&self) -> i32 { 103 let window = self.window.borrow(); 104 (*window).y() 105 } 106 107 /// 返回宽度值 108 pub fn width(&self) -> u32 { 109 let window = self.window.borrow(); 110 (*window).width() 111 } 112 113 /// 返回高度值 114 pub fn height(&self) -> u32 { 115 let window = self.window.borrow(); 116 (*window).height() 117 } 118 119 /// 窗口标题 120 pub fn title(&self) -> String { 121 let window = self.window.borrow(); 122 (*window).title() 123 } 124 125 /// 改变窗口位置 126 pub fn set_pos(&self, x: i32, y: i32) { 127 let mut window = self.window.borrow_mut(); 128 (*window).set_pos(x, y); 129 } 130 131 /// 改变窗口大小 132 pub fn set_size(&self, width: u32, height: u32) { 133 let mut window = self.window.borrow_mut(); 134 (*window).set_size(width, height); 135 } 136 137 /// 改变窗口标题 138 pub fn set_title(&self, title: &str) { 139 let mut window = self.window.borrow_mut(); 140 (*window).set_title(title); 141 } 142 143 /// 关闭窗口 144 pub fn close(&self) { 145 self.running.set(false); 146 } 147 148 /// 添加子组件,返回子组件id 149 pub fn add_child<T: Widget>(&self, widget: &Arc<T>) -> usize { 150 let mut widgets = self.widgets.borrow_mut(); 151 let id = widgets.len(); 152 widgets.push(widget.clone()); 153 154 return id; 155 } 156 157 /// 渲染面板(渲染子组件数组) 158 pub fn draw(&self) { 159 let mut window = self.window.borrow_mut(); 160 let mut renderer = PanelRenderer::new(&mut window); 161 162 for widget in self.widgets.borrow().iter() { 163 self.draw_widget(&mut renderer, widget); 164 } 165 166 renderer.sync(); 167 } 168 169 /// 渲染单个组件 170 pub fn draw_widget(&self, renderer: &mut dyn Renderer, widget: &Arc<dyn Widget>) { 171 widget.update(); 172 widget.draw(renderer); 173 174 // 渲染子组件 175 for child in widget.children().borrow().iter() { 176 self.draw_widget(renderer, child); 177 } 178 } 179 } 180