fyrox_ui/inspector/editors/
inspectable.rs1use crate::{
24 core::reflect::prelude::*,
25 inspector::{
26 editors::{
27 PropertyEditorBuildContext, PropertyEditorDefinition, PropertyEditorInstance,
28 PropertyEditorMessageContext, PropertyEditorTranslationContext,
29 },
30 make_expander_container, FieldKind, Inspector, InspectorBuilder, InspectorContext,
31 InspectorError, InspectorMessage, PropertyChanged,
32 },
33 message::{MessageDirection, UiMessage},
34 widget::WidgetBuilder,
35};
36use fyrox_core::pool::Handle;
37use fyrox_core::PhantomDataSendSync;
38use fyrox_graph::BaseSceneGraph;
39use std::{
40 any::TypeId,
41 fmt::{Debug, Formatter},
42};
43
44pub struct InspectablePropertyEditorDefinition<T>
50where
51 T: Reflect + 'static,
52{
53 #[allow(dead_code)]
54 phantom: PhantomDataSendSync<T>,
55}
56
57impl<T> InspectablePropertyEditorDefinition<T>
58where
59 T: Reflect + 'static,
60{
61 pub fn new() -> Self {
62 Self {
63 phantom: Default::default(),
64 }
65 }
66}
67
68impl<T> Debug for InspectablePropertyEditorDefinition<T>
69where
70 T: Reflect + 'static,
71{
72 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 writeln!(f, "InspectablePropertyEditorDefinition")
74 }
75}
76
77impl<T> PropertyEditorDefinition for InspectablePropertyEditorDefinition<T>
78where
79 T: Reflect + 'static,
80{
81 fn value_type_id(&self) -> TypeId {
82 TypeId::of::<T>()
83 }
84
85 fn create_instance(
86 &self,
87 ctx: PropertyEditorBuildContext,
88 ) -> Result<PropertyEditorInstance, InspectorError> {
89 let value = ctx.property_info.cast_value::<T>()?;
90
91 let inspector_context = InspectorContext::from_object(
92 value,
93 ctx.build_context,
94 ctx.definition_container.clone(),
95 ctx.environment.clone(),
96 ctx.sync_flag,
97 ctx.layer_index + 1,
98 ctx.generate_property_string_values,
99 ctx.filter,
100 ctx.name_column_width,
101 );
102
103 let editor;
104 let container = make_expander_container(
105 ctx.layer_index,
106 ctx.property_info.display_name,
107 ctx.property_info.description,
108 Handle::NONE,
109 {
110 editor = InspectorBuilder::new(WidgetBuilder::new())
111 .with_context(inspector_context)
112 .build(ctx.build_context);
113 editor
114 },
115 ctx.name_column_width,
116 ctx.build_context,
117 );
118
119 Ok(PropertyEditorInstance::Custom { container, editor })
120 }
121
122 fn create_message(
126 &self,
127 ctx: PropertyEditorMessageContext,
128 ) -> Result<Option<UiMessage>, InspectorError> {
129 let value = ctx.property_info.cast_value::<T>()?;
130
131 let mut error_group = Vec::new();
132
133 let inspector_context = ctx
134 .ui
135 .node(ctx.instance)
136 .cast::<Inspector>()
137 .expect("Must be Inspector!")
138 .context()
139 .clone();
140 if let Err(e) = inspector_context.sync(
141 value,
142 ctx.ui,
143 ctx.layer_index + 1,
144 ctx.generate_property_string_values,
145 ctx.filter,
146 ) {
147 error_group.extend(e)
148 }
149
150 if error_group.is_empty() {
151 Ok(None)
152 } else {
153 Err(InspectorError::Group(error_group))
154 }
155 }
156
157 fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
158 if let Some(InspectorMessage::PropertyChanged(msg)) = ctx.message.data::<InspectorMessage>()
159 {
160 if ctx.message.direction() == MessageDirection::FromWidget {
161 return Some(PropertyChanged {
162 name: ctx.name.to_owned(),
163 owner_type_id: ctx.owner_type_id,
164 value: FieldKind::Inspectable(Box::new(msg.clone())),
165 });
166 }
167 }
168
169 None
170 }
171}