xref: /StarryEngine/starry_applications/src/asset_manager/code/asset_item_list.rs (revision 731cae0674923fcc85c6e683a2eee596eb642796)
1 use std::{
2     any::Any,
3     cell::{Cell, RefCell},
4     str::FromStr,
5     sync::{Arc, Weak},
6 };
7 
8 use starry_client::base::{color::Color, renderer::Renderer};
9 use starry_toolkit::{
10     base::{panel::Panel, rect::Rect, vector2::Vector2},
11     traits::text::Text,
12     widgets::{
13         image::Image,
14         label::{Label, LabelOverflowType},
15         PivotType, Widget,
16     },
17 };
18 
19 pub struct AssetItemList {
20     self_ref: RefCell<Weak<AssetItemList>>,
21     pub rect: Cell<Rect>,
22     pivot: Cell<PivotType>,
23     pivot_offset: Cell<Vector2>,
24     parent: RefCell<Option<Arc<dyn Widget>>>,
25     children: RefCell<Vec<Arc<dyn Widget>>>,
26     panel: RefCell<Option<Arc<Panel>>>,
27     /// 缓存值
28     cache_focused: Cell<bool>,
29     pub file_path: RefCell<String>,
30 }
31 
32 impl AssetItemList {
33     pub const ITEM_WIDTH: u32 = 1024;
34     pub const ITEM_HEIGHT: u32 = 32;
35 
new(file_name: &str, is_dir: bool) -> Arc<Self>36     pub fn new(file_name: &str, is_dir: bool) -> Arc<Self> {
37         let item = Arc::new(AssetItemList {
38             self_ref: RefCell::new(Weak::default()),
39             rect: Cell::new(Rect::new(0, 0, Self::ITEM_WIDTH, Self::ITEM_HEIGHT)),
40             pivot: Cell::new(PivotType::TopLeft),
41             pivot_offset: Cell::new(Vector2::new(0, 0)),
42             children: RefCell::new(Vec::new()),
43             parent: RefCell::new(None),
44             panel: RefCell::new(None),
45             cache_focused: Cell::new(false),
46             file_path: RefCell::new(String::from_str(file_name).unwrap()),
47         });
48 
49         (*item.self_ref.borrow_mut()) = Arc::downgrade(&item);
50 
51         // 背景Image
52         let bg = Image::new_from_color(
53             Self::ITEM_WIDTH,
54             Self::ITEM_HEIGHT,
55             Color::rgba(0, 255, 255, 64),
56         );
57         bg.set_pivot_type(PivotType::Center);
58         item.add_child(bg);
59 
60         // 文件名Label
61         let name = Label::new();
62         name.set_adapt_type(LabelOverflowType::Omit);
63         name.resize(256, 16);
64         name.set_text(file_name);
65         name.set_pivot_type(PivotType::Left);
66         name.set_pivot_offset(Vector2::new(20, 0));
67         name.set_text_pivot_type(PivotType::Left);
68         item.add_child(name);
69 
70         // 文件类型Label
71         let file_type = Label::new();
72         file_type.set_adapt_type(LabelOverflowType::ShinkToFit);
73         let type_name = if is_dir { "direction" } else { "file" };
74         file_type.set_text(type_name);
75         file_type.set_pivot_type(PivotType::Center);
76         item.add_child(file_type);
77 
78         return item;
79     }
80 }
81 
82 impl Widget for AssetItemList {
self_ref(&self) -> Arc<dyn Widget>83     fn self_ref(&self) -> Arc<dyn Widget> {
84         self.self_ref.borrow().upgrade().unwrap()
85     }
86 
as_any_ref(&self) -> &dyn Any87     fn as_any_ref(&self) -> &dyn Any {
88         self
89     }
90 
name(&self) -> &str91     fn name(&self) -> &str {
92         "AssetItem_List"
93     }
94 
rect(&self) -> &Cell<Rect>95     fn rect(&self) -> &Cell<Rect> {
96         &self.rect
97     }
98 
pivot(&self) -> &Cell<PivotType>99     fn pivot(&self) -> &Cell<PivotType> {
100         &self.pivot
101     }
102 
pivot_offset(&self) -> &Cell<Vector2>103     fn pivot_offset(&self) -> &Cell<Vector2> {
104         &self.pivot_offset
105     }
106 
parent(&self) -> &RefCell<Option<Arc<dyn Widget>>>107     fn parent(&self) -> &RefCell<Option<Arc<dyn Widget>>> {
108         &self.parent
109     }
110 
children(&self) -> &RefCell<Vec<Arc<dyn Widget>>>111     fn children(&self) -> &RefCell<Vec<Arc<dyn Widget>>> {
112         &self.children
113     }
114 
panel(&self) -> &RefCell<Option<Arc<Panel>>>115     fn panel(&self) -> &RefCell<Option<Arc<Panel>>> {
116         &self.panel
117     }
118 
draw(&self, renderer: &mut dyn Renderer, focused: bool)119     fn draw(&self, renderer: &mut dyn Renderer, focused: bool) {
120         if focused != self.cache_focused.get() {
121             self.cache_focused.set(focused);
122         }
123 
124         for child in self.children.borrow().iter() {
125             child.draw(renderer, focused);
126         }
127     }
128 }
129