fyrox_ui/inspector/editors/
matrix2.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21use crate::{
22    core::{algebra::SMatrix, num_traits::NumCast},
23    inspector::{
24        editors::{
25            PropertyEditorBuildContext, PropertyEditorDefinition, PropertyEditorInstance,
26            PropertyEditorMessageContext, PropertyEditorTranslationContext,
27        },
28        FieldKind, InspectorError, PropertyChanged,
29    },
30    matrix::{MatrixEditorBuilder, MatrixEditorMessage},
31    message::{MessageDirection, UiMessage},
32    numeric::NumericType,
33    widget::WidgetBuilder,
34    Thickness,
35};
36use std::{any::TypeId, marker::PhantomData};
37
38#[derive(Debug)]
39pub struct MatrixPropertyEditorDefinition<const R: usize, const C: usize, T: NumericType> {
40    pub phantom: PhantomData<T>,
41}
42
43impl<const R: usize, const C: usize, T: NumericType> Default
44    for MatrixPropertyEditorDefinition<R, C, T>
45{
46    fn default() -> Self {
47        Self {
48            phantom: PhantomData,
49        }
50    }
51}
52
53impl<const R: usize, const C: usize, T: NumericType> PropertyEditorDefinition
54    for MatrixPropertyEditorDefinition<R, C, T>
55{
56    fn value_type_id(&self) -> TypeId {
57        TypeId::of::<SMatrix<T, R, C>>()
58    }
59
60    fn create_instance(
61        &self,
62        ctx: PropertyEditorBuildContext,
63    ) -> Result<PropertyEditorInstance, InspectorError> {
64        let value = ctx.property_info.cast_value::<SMatrix<T, R, C>>()?;
65        Ok(PropertyEditorInstance::Simple {
66            editor: MatrixEditorBuilder::new(
67                WidgetBuilder::new().with_margin(Thickness::uniform(1.0)),
68            )
69            .with_min(SMatrix::repeat(
70                ctx.property_info
71                    .min_value
72                    .and_then(NumCast::from)
73                    .unwrap_or_else(T::min_value),
74            ))
75            .with_max(SMatrix::repeat(
76                ctx.property_info
77                    .max_value
78                    .and_then(NumCast::from)
79                    .unwrap_or_else(T::max_value),
80            ))
81            .with_step(SMatrix::repeat(
82                ctx.property_info
83                    .step
84                    .and_then(NumCast::from)
85                    .unwrap_or_else(T::one),
86            ))
87            .with_value(*value)
88            .build(ctx.build_context),
89        })
90    }
91
92    fn create_message(
93        &self,
94        ctx: PropertyEditorMessageContext,
95    ) -> Result<Option<UiMessage>, InspectorError> {
96        let value = ctx.property_info.cast_value::<SMatrix<T, R, C>>()?;
97        Ok(Some(MatrixEditorMessage::value(
98            ctx.instance,
99            MessageDirection::ToWidget,
100            *value,
101        )))
102    }
103
104    fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
105        if ctx.message.direction() == MessageDirection::FromWidget {
106            if let Some(MatrixEditorMessage::Value(value)) =
107                ctx.message.data::<MatrixEditorMessage<R, C, T>>()
108            {
109                return Some(PropertyChanged {
110                    owner_type_id: ctx.owner_type_id,
111                    name: ctx.name.to_string(),
112                    value: FieldKind::object(*value),
113                });
114            }
115        }
116        None
117    }
118}