Skip to main content

fyrox_ui/inspector/editors/
cell.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::{reflect::prelude::*, reflect::FieldValue},
23    inspector::{
24        editors::{
25            PropertyEditorBuildContext, PropertyEditorDefinition, PropertyEditorInstance,
26            PropertyEditorMessageContext, PropertyEditorTranslationContext,
27        },
28        InspectorError, PropertyChanged,
29    },
30    message::UiMessage,
31};
32use fyrox_core::PhantomDataSendSync;
33use std::{
34    any::TypeId,
35    cell::Cell,
36    fmt::{Debug, Formatter},
37};
38
39pub struct CellPropertyEditorDefinition<T>
40where
41    T: FieldValue + Copy,
42{
43    #[allow(dead_code)]
44    phantom: PhantomDataSendSync<T>,
45}
46
47impl<T> CellPropertyEditorDefinition<T>
48where
49    T: FieldValue + Copy,
50{
51    pub fn new() -> Self {
52        Self {
53            phantom: Default::default(),
54        }
55    }
56}
57
58impl<T> Debug for CellPropertyEditorDefinition<T>
59where
60    T: Reflect + FieldValue + Copy,
61{
62    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63        writeln!(f, "CellPropertyEditorDefinition")
64    }
65}
66
67impl<T> PropertyEditorDefinition for CellPropertyEditorDefinition<T>
68where
69    T: Reflect + FieldValue + Copy,
70{
71    fn value_type_id(&self) -> TypeId {
72        TypeId::of::<Cell<T>>()
73    }
74
75    fn create_instance(
76        &self,
77        ctx: PropertyEditorBuildContext,
78    ) -> Result<PropertyEditorInstance, InspectorError> {
79        if let Some(definition) = ctx
80            .definition_container
81            .definitions()
82            .get(&TypeId::of::<T>())
83        {
84            let property_info = ctx.property_info;
85
86            let value = property_info.cast_value::<Cell<T>>()?.get();
87
88            let proxy_property_info = FieldRef {
89                metadata: &FieldMetadata {
90                    name: property_info.name,
91                    display_name: property_info.display_name,
92                    read_only: property_info.read_only,
93                    immutable_collection: property_info.immutable_collection,
94                    min_value: property_info.min_value,
95                    max_value: property_info.max_value,
96                    step: property_info.step,
97                    precision: property_info.precision,
98                    tag: property_info.tag,
99                    doc: property_info.doc,
100                },
101                value: &value,
102            };
103
104            definition
105                .property_editor
106                .create_instance(PropertyEditorBuildContext {
107                    build_context: ctx.build_context,
108                    property_info: &proxy_property_info,
109                    environment: ctx.environment.clone(),
110                    definition_container: ctx.definition_container.clone(),
111                    layer_index: ctx.layer_index,
112                    generate_property_string_values: ctx.generate_property_string_values,
113                    filter: ctx.filter,
114                    name_column_width: ctx.name_column_width,
115                    base_path: ctx.base_path.clone(),
116                    has_parent_object: ctx.has_parent_object,
117                })
118        } else {
119            Err(InspectorError::Custom("No editor!".to_string()))
120        }
121    }
122
123    fn create_message(
124        &self,
125        ctx: PropertyEditorMessageContext,
126    ) -> Result<Option<UiMessage>, InspectorError> {
127        if let Some(definition) = ctx
128            .definition_container
129            .definitions()
130            .get(&TypeId::of::<T>())
131        {
132            let property_info = ctx.property_info;
133
134            let value = ctx.property_info.cast_value::<Cell<T>>()?.get();
135
136            let proxy_property_info = FieldRef {
137                metadata: &FieldMetadata {
138                    name: property_info.name,
139                    display_name: property_info.display_name,
140                    read_only: property_info.read_only,
141                    immutable_collection: property_info.immutable_collection,
142                    min_value: property_info.min_value,
143                    max_value: property_info.max_value,
144                    step: property_info.step,
145                    precision: property_info.precision,
146                    tag: property_info.tag,
147                    doc: property_info.doc,
148                },
149                value: &value,
150            };
151
152            return definition
153                .property_editor
154                .create_message(PropertyEditorMessageContext {
155                    property_info: &proxy_property_info,
156                    environment: ctx.environment.clone(),
157                    definition_container: ctx.definition_container.clone(),
158                    instance: ctx.instance,
159                    layer_index: ctx.layer_index,
160                    ui: ctx.ui,
161                    generate_property_string_values: ctx.generate_property_string_values,
162                    filter: ctx.filter,
163                    name_column_width: ctx.name_column_width,
164                    base_path: ctx.base_path.clone(),
165                    has_parent_object: ctx.has_parent_object,
166                });
167        }
168
169        Err(InspectorError::Custom("No editor!".to_string()))
170    }
171
172    fn translate_message(&self, ctx: PropertyEditorTranslationContext) -> Option<PropertyChanged> {
173        // Try translate other messages using inner property editor.
174        if let Some(definition) = ctx
175            .definition_container
176            .definitions()
177            .get(&TypeId::of::<T>())
178        {
179            return definition.property_editor.translate_message(
180                PropertyEditorTranslationContext {
181                    environment: ctx.environment.clone(),
182                    name: ctx.name,
183
184                    message: ctx.message,
185                    definition_container: ctx.definition_container.clone(),
186                },
187            );
188        }
189
190        None
191    }
192}