use crate::{
core::{reflect::prelude::*, reflect::FieldValue},
inspector::{
editors::{
PropertyEditorBuildContext, PropertyEditorDefinition, PropertyEditorInstance,
PropertyEditorMessageContext, PropertyEditorTranslationContext,
},
InspectorError, PropertyChanged,
},
message::UiMessage,
};
use fyrox_core::PhantomDataSendSync;
use std::{
any::TypeId,
cell::Cell,
fmt::{Debug, Formatter},
};
pub struct CellPropertyEditorDefinition<T>
where
T: FieldValue + Copy,
{
#[allow(dead_code)]
phantom: PhantomDataSendSync<T>,
}
impl<T> CellPropertyEditorDefinition<T>
where
T: FieldValue + Copy,
{
pub fn new() -> Self {
Self {
phantom: Default::default(),
}
}
}
impl<T> Debug for CellPropertyEditorDefinition<T>
where
T: Reflect + FieldValue + Copy,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
writeln!(f, "CellPropertyEditorDefinition")
}
}
impl<T> PropertyEditorDefinition for CellPropertyEditorDefinition<T>
where
T: Reflect + FieldValue + Copy,
{
fn value_type_id(&self) -> TypeId {
TypeId::of::<Cell<T>>()
}
fn create_instance(
&self,
ctx: PropertyEditorBuildContext,
) -> Result<PropertyEditorInstance, InspectorError> {
if let Some(definition) = ctx
.definition_container
.definitions()
.get(&TypeId::of::<T>())
{
let property_info = ctx.property_info;
let value = property_info.cast_value::<Cell<T>>()?.get();
let proxy_property_info = FieldRef {
metadata: &FieldMetadata {
name: property_info.name,
display_name: property_info.display_name,
read_only: property_info.read_only,
immutable_collection: property_info.immutable_collection,
min_value: property_info.min_value,
max_value: property_info.max_value,
step: property_info.step,
precision: property_info.precision,
tag: property_info.tag,
doc: property_info.doc,
},
value: &value,
};
definition
.property_editor
.create_instance(PropertyEditorBuildContext {
build_context: ctx.build_context,
property_info: &proxy_property_info,
environment: ctx.environment.clone(),
definition_container: ctx.definition_container.clone(),
layer_index: ctx.layer_index,
generate_property_string_values: ctx.generate_property_string_values,
filter: ctx.filter,
name_column_width: ctx.name_column_width,
base_path: ctx.base_path.clone(),
has_parent_object: ctx.has_parent_object,
})
} else {
Err(InspectorError::Custom("No editor!".to_string()))
}
}
fn create_message(
&self,
ctx: PropertyEditorMessageContext,
) -> Result<Option<UiMessage>, InspectorError> {
if let Some(definition) = ctx
.definition_container
.definitions()
.get(&TypeId::of::<T>())
{
let property_info = ctx.property_info;
let value = ctx.property_info.cast_value::<Cell<T>>()?.get();
let proxy_property_info = FieldRef {
metadata: &FieldMetadata {
name: property_info.name,
display_name: property_info.display_name,
read_only: property_info.read_only,
immutable_collection: property_info.immutable_collection,
min_value: property_info.min_value,
max_value: property_info.max_value,
step: property_info.step,
precision: property_info.precision,
tag: property_info.tag,
doc: property_info.doc,
},
value: &value,
};
return definition
.property_editor
.create_message(PropertyEditorMessageContext {
property_info: &proxy_property_info,
environment: ctx.environment.clone(),
definition_container: ctx.definition_container.clone(),
instance: ctx.instance,
layer_index: ctx.layer_index,
ui: ctx.ui,
generate_property_string_values: ctx.generate_property_string_values,
filter: ctx.filter,
name_column_width: ctx.name_column_width,
base_path: ctx.base_path.clone(),
has_parent_object: ctx.has_parent_object,
});
}
Err(InspectorError::Custom("No editor!".to_string()))
}
fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
if let Some(definition) = ctx
.definition_container
.definitions()
.get(&TypeId::of::<T>())
{
return definition.property_editor.translate_message(
PropertyEditorTranslationContext {
environment: ctx.environment.clone(),
name: ctx.name,
message: ctx.message,
definition_container: ctx.definition_container.clone(),
},
);
}
None
}
}