|
@@ -0,0 +1,176 @@
|
|
|
+
|
|
|
+use std::{cell::{Cell, RefCell}, sync::Arc};
|
|
|
+
|
|
|
+use starry_client::{base::{color::Color, renderer::{RenderMode, Renderer}}, window::Window};
|
|
|
+
|
|
|
+use crate::widgets::Widget;
|
|
|
+
|
|
|
+use super::rect::Rect;
|
|
|
+
|
|
|
+/// 面板渲染器
|
|
|
+pub struct PanelRenderer<'a> {
|
|
|
+ /// 客户端窗口
|
|
|
+ window: & 'a mut Window,
|
|
|
+}
|
|
|
+
|
|
|
+impl<'a> PanelRenderer<'a> {
|
|
|
+ pub fn new(window: &'a mut Window) -> Self{
|
|
|
+ PanelRenderer {
|
|
|
+ window,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'a> Renderer for PanelRenderer<'a> {
|
|
|
+ fn width(&self) -> u32 {
|
|
|
+ self.window.width()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn height(&self) -> u32 {
|
|
|
+ self.window.height()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn data(&self) -> &[Color] {
|
|
|
+ self.window.data()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn data_mut(&mut self) -> &mut [Color] {
|
|
|
+ self.window.data_mut()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn sync(&mut self) -> bool {
|
|
|
+ self.window.sync()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn mode(&self) -> &Cell<RenderMode> {
|
|
|
+ &self.window.mode()
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO
|
|
|
+ // fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
|
|
|
+ // }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'a> Drop for PanelRenderer<'a> {
|
|
|
+ fn drop(&mut self) {
|
|
|
+ self.window.sync();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// UI面板类作为容器管理一组UI组件(UI-Widget)
|
|
|
+/// 拥有一个窗口对象用于渲染和事件传递
|
|
|
+pub struct Panel {
|
|
|
+ /// 客户端窗口对象
|
|
|
+ window: RefCell<Window>,
|
|
|
+ /// 子组件数组
|
|
|
+ pub widgets: RefCell<Vec<Arc<dyn Widget>>>,
|
|
|
+ /// 窗口是否打开
|
|
|
+ pub running: Cell<bool>,
|
|
|
+}
|
|
|
+
|
|
|
+impl Panel {
|
|
|
+ pub fn new(rect: Rect, title: &str) -> Self {
|
|
|
+ Panel::from_window(
|
|
|
+ Window::new(rect.x, rect.y, rect.width, rect.height, title)
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn from_window(window: Window) -> Self {
|
|
|
+ Panel {
|
|
|
+ window: RefCell::new(window),
|
|
|
+ widgets: RefCell::new(Vec::new()),
|
|
|
+ running: Cell::new(true),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 获得客户端窗口对象
|
|
|
+ pub fn into_window(self) -> Window {
|
|
|
+ self.window.into_inner()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 返回x坐标
|
|
|
+ pub fn x(&self) -> i32 {
|
|
|
+ let window = self.window.borrow();
|
|
|
+ (*window).x()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 返回y坐标
|
|
|
+ pub fn y(&self) -> i32 {
|
|
|
+ let window = self.window.borrow();
|
|
|
+ (*window).y()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 返回宽度值
|
|
|
+ pub fn width(&self) -> u32 {
|
|
|
+ let window = self.window.borrow();
|
|
|
+ (*window).width()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 返回高度值
|
|
|
+ pub fn height(&self) -> u32 {
|
|
|
+ let window = self.window.borrow();
|
|
|
+ (*window).height()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 窗口标题
|
|
|
+ pub fn title(&self) -> String {
|
|
|
+ let window = self.window.borrow();
|
|
|
+ (*window).title()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 改变窗口位置
|
|
|
+ pub fn set_pos(&self, x: i32, y: i32) {
|
|
|
+ let mut window = self.window.borrow_mut();
|
|
|
+ (*window).set_pos(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 改变窗口大小
|
|
|
+ pub fn set_size(&self, width: u32, height: u32) {
|
|
|
+ let mut window = self.window.borrow_mut();
|
|
|
+ (*window).set_size(width, height);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 改变窗口标题
|
|
|
+ pub fn set_title(&self, title: &str) {
|
|
|
+ let mut window = self.window.borrow_mut();
|
|
|
+ (*window).set_title(title);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 关闭窗口
|
|
|
+ pub fn close(&self) {
|
|
|
+ self.running.set(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 添加子组件,返回子组件id
|
|
|
+ pub fn add_child<T: Widget>(&self, widget: &Arc<T>) -> usize {
|
|
|
+ let mut widgets = self.widgets.borrow_mut();
|
|
|
+ let id = widgets.len();
|
|
|
+ widgets.push(widget.clone());
|
|
|
+
|
|
|
+ return id;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 渲染面板(渲染子组件数组)
|
|
|
+ pub fn draw(&self) {
|
|
|
+ let mut window = self.window.borrow_mut();
|
|
|
+ let mut renderer = PanelRenderer::new(&mut window);
|
|
|
+
|
|
|
+ for widget in self.widgets.borrow().iter() {
|
|
|
+ self.draw_widget(&mut renderer, widget);
|
|
|
+ }
|
|
|
+
|
|
|
+ renderer.sync();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 渲染单个组件
|
|
|
+ pub fn draw_widget(&self, renderer: &mut dyn Renderer, widget: &Arc<dyn Widget>) {
|
|
|
+ widget.update();
|
|
|
+ widget.draw(renderer);
|
|
|
+
|
|
|
+ // 渲染子组件
|
|
|
+ for child in widget.children().borrow().iter() {
|
|
|
+ self.draw_widget(renderer, child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|