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 FieldAction, 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 VecEditorBuilder::new(WidgetBuilder::new().with_margin(Thickness::uniform(1.0)))
65 .with_min(SVector::repeat(
66 ctx.property_info
67 .min_value
68 .and_then(NumCast::from)
69 .unwrap_or_else(T::min_value),
70 ))
71 .with_max(SVector::repeat(
72 ctx.property_info
73 .max_value
74 .and_then(NumCast::from)
75 .unwrap_or_else(T::max_value),
76 ))
77 .with_step(SVector::repeat(
78 ctx.property_info
79 .step
80 .and_then(NumCast::from)
81 .unwrap_or_else(T::one),
82 ))
83 .with_value(*value)
84 .build(ctx.build_context),
85 ))
86 }
87
88 fn create_message(
89 &self,
90 ctx: PropertyEditorMessageContext,
91 ) -> Result<Option<UiMessage>, InspectorError> {
92 let value = ctx.property_info.cast_value::<SVector<T, D>>()?;
93 Ok(Some(
94 UiMessage::with_data(VecEditorMessage::Value(*value)).with_destination(ctx.instance),
95 ))
96 }
97
98 fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
99 if ctx.message.direction() == MessageDirection::FromWidget {
100 if let Some(VecEditorMessage::Value(value)) =
101 ctx.message.data::<VecEditorMessage<T, D>>()
102 {
103 return Some(PropertyChanged {
104 name: ctx.name.to_string(),
105 action: FieldAction::object(*value),
106 });
107 }
108 }
109 None
110 }
111}
112
113pub type Vec2PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 2>;
114pub type Vec3PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 3>;
115pub type Vec4PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 4>;
116pub type Vec5PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 5>;
117pub type Vec6PropertyEditorDefinition<T> = VecPropertyEditorDefinition<T, 6>;