fyrox_ui/inspector/editors/
vec.rs1use crate::{
22 core::{algebra::SVector, num_traits::NumCast},
23 inspector::{
24 editors::{
25 PropertyEditorBuildContext, PropertyEditorDefinition, PropertyEditorInstance,
26 PropertyEditorMessageContext, PropertyEditorTranslationContext,
27 },
28 FieldKind, InspectorError, PropertyChanged,
29 },
30 message::{MessageDirection, UiMessage},
31 numeric::NumericType,
32 vec::{VecEditorBuilder, VecEditorMessage},
33 widget::WidgetBuilder,
34 Thickness,
35};
36use std::{any::TypeId, marker::PhantomData};
37
38#[derive(Debug)]
39pub struct VecPropertyEditorDefinition<T: NumericType, const D: usize> {
40 pub phantom: PhantomData<T>,
41}
42
43impl<T: NumericType, const D: usize> Default for VecPropertyEditorDefinition<T, D> {
44 fn default() -> Self {
45 Self {
46 phantom: PhantomData,
47 }
48 }
49}
50
51impl<T: NumericType, const D: usize> PropertyEditorDefinition
52 for VecPropertyEditorDefinition<T, D>
53{
54 fn value_type_id(&self) -> TypeId {
55 TypeId::of::<SVector<T, D>>()
56 }
57
58 fn create_instance(
59 &self,
60 ctx: PropertyEditorBuildContext,
61 ) -> Result<PropertyEditorInstance, InspectorError> {
62 let value = ctx.property_info.cast_value::<SVector<T, D>>()?;
63 Ok(PropertyEditorInstance::Simple {
64 editor: VecEditorBuilder::new(
65 WidgetBuilder::new().with_margin(Thickness::uniform(1.0)),
66 )
67 .with_min(SVector::repeat(
68 ctx.property_info
69 .min_value
70 .and_then(NumCast::from)
71 .unwrap_or_else(T::min_value),
72 ))
73 .with_max(SVector::repeat(
74 ctx.property_info
75 .max_value
76 .and_then(NumCast::from)
77 .unwrap_or_else(T::max_value),
78 ))
79 .with_step(SVector::repeat(
80 ctx.property_info
81 .step
82 .and_then(NumCast::from)
83 .unwrap_or_else(T::one),
84 ))
85 .with_value(*value)
86 .build(ctx.build_context),
87 })
88 }
89
90 fn create_message(
91 &self,
92 ctx: PropertyEditorMessageContext,
93 ) -> Result<Option<UiMessage>, InspectorError> {
94 let value = ctx.property_info.cast_value::<SVector<T, D>>()?;
95 Ok(Some(VecEditorMessage::value(
96 ctx.instance,
97 MessageDirection::ToWidget,
98 *value,
99 )))
100 }
101
102 fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
103 if ctx.message.direction() == MessageDirection::FromWidget {
104 if let Some(VecEditorMessage::Value(value)) =
105 ctx.message.data::<VecEditorMessage<T, D>>()
106 {
107 return Some(PropertyChanged {
108 owner_type_id: ctx.owner_type_id,
109 name: ctx.name.to_string(),
110 value: FieldKind::object(*value),
111 });
112 }
113 }
114 None
115 }
116}
117
118pub type Vec2PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 2>;
119pub type Vec3PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 3>;
120pub type Vec4PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 4>;
121pub type Vec5PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 5>;
122pub type Vec6PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 6>;