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