fyrox_ui/inspector/editors/
numeric.rs1use crate::{
22 core::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, NumericUpDownBuilder, NumericUpDownMessage},
32 widget::WidgetBuilder,
33 Thickness,
34};
35use std::{any::TypeId, marker::PhantomData};
36
37#[derive(Debug)]
38pub struct NumericPropertyEditorDefinition<T>
39where
40 T: NumericType,
41{
42 phantom: PhantomData<T>,
43}
44
45impl<T> Default for NumericPropertyEditorDefinition<T>
46where
47 T: NumericType,
48{
49 fn default() -> Self {
50 Self {
51 phantom: PhantomData,
52 }
53 }
54}
55
56impl<T> PropertyEditorDefinition for NumericPropertyEditorDefinition<T>
57where
58 T: NumericType,
59{
60 fn value_type_id(&self) -> TypeId {
61 TypeId::of::<T>()
62 }
63
64 fn create_instance(
65 &self,
66 ctx: PropertyEditorBuildContext,
67 ) -> Result<PropertyEditorInstance, InspectorError> {
68 let value = ctx.property_info.cast_value::<T>()?;
69 Ok(PropertyEditorInstance::simple(
70 NumericUpDownBuilder::new(WidgetBuilder::new().with_margin(Thickness::top_bottom(1.0)))
71 .with_min_value(
72 ctx.property_info
73 .min_value
74 .and_then(NumCast::from)
75 .unwrap_or_else(T::min_value),
76 )
77 .with_max_value(
78 ctx.property_info
79 .max_value
80 .and_then(NumCast::from)
81 .unwrap_or_else(T::max_value),
82 )
83 .with_step(
84 ctx.property_info
85 .step
86 .and_then(NumCast::from)
87 .unwrap_or_else(T::one),
88 )
89 .with_precision(ctx.property_info.precision.unwrap_or(3))
90 .with_value(*value)
91 .build(ctx.build_context),
92 ))
93 }
94
95 fn create_message(
96 &self,
97 ctx: PropertyEditorMessageContext,
98 ) -> Result<Option<UiMessage>, InspectorError> {
99 let value = ctx.property_info.cast_value::<T>()?;
100 Ok(Some(UiMessage::for_widget(
101 ctx.instance,
102 NumericUpDownMessage::Value(*value),
103 )))
104 }
105
106 fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
107 if ctx.message.direction() == MessageDirection::FromWidget {
108 if let Some(NumericUpDownMessage::Value(value)) =
109 ctx.message.data::<NumericUpDownMessage<T>>()
110 {
111 return Some(PropertyChanged {
112 name: ctx.name.to_string(),
113
114 value: FieldKind::object(*value),
115 });
116 }
117 }
118
119 None
120 }
121}