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 editor: NumericUpDownBuilder::new(
71 WidgetBuilder::new().with_margin(Thickness::top_bottom(1.0)),
72 )
73 .with_min_value(
74 ctx.property_info
75 .min_value
76 .and_then(NumCast::from)
77 .unwrap_or_else(T::min_value),
78 )
79 .with_max_value(
80 ctx.property_info
81 .max_value
82 .and_then(NumCast::from)
83 .unwrap_or_else(T::max_value),
84 )
85 .with_step(
86 ctx.property_info
87 .step
88 .and_then(NumCast::from)
89 .unwrap_or_else(T::one),
90 )
91 .with_precision(ctx.property_info.precision.unwrap_or(3))
92 .with_value(*value)
93 .build(ctx.build_context),
94 })
95 }
96
97 fn create_message(
98 &self,
99 ctx: PropertyEditorMessageContext,
100 ) -> Result<Option<UiMessage>, InspectorError> {
101 let value = ctx.property_info.cast_value::<T>()?;
102 Ok(Some(NumericUpDownMessage::value(
103 ctx.instance,
104 MessageDirection::ToWidget,
105 *value,
106 )))
107 }
108
109 fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
110 if ctx.message.direction() == MessageDirection::FromWidget {
111 if let Some(NumericUpDownMessage::Value(value)) =
112 ctx.message.data::<NumericUpDownMessage<T>>()
113 {
114 return Some(PropertyChanged {
115 name: ctx.name.to_string(),
116
117 value: FieldKind::object(*value),
118 });
119 }
120 }
121
122 None
123 }
124}