1#![warn(missing_docs)]
25
26use crate::{
27 button::{ButtonBuilder, ButtonMessage},
28 core::{pool::Handle, reflect::prelude::*, type_traits::prelude::*, visitor::prelude::*},
29 define_constructor, define_widget_deref,
30 grid::{Column, GridBuilder, Row},
31 message::{MessageDirection, UiMessage},
32 text::{TextBuilder, TextMessage},
33 widget::{Widget, WidgetBuilder},
34 BuildContext, Control, Thickness, UiNode, UserInterface, VerticalAlignment,
35};
36
37use fyrox_core::uuid_provider;
38use fyrox_graph::constructor::{ConstructorProvider, GraphNodeConstructor};
39use std::ops::{Deref, DerefMut};
40
41#[derive(Debug, Clone, PartialEq, Eq)]
43pub enum UuidEditorMessage {
44 Value(Uuid),
46}
47
48impl UuidEditorMessage {
49 define_constructor!(
50 UuidEditorMessage:Value => fn value(Uuid), layout: false
52 );
53}
54
55#[derive(Default, Clone, Visit, Reflect, Debug, ComponentProvider)]
74#[reflect(derived_type = "UiNode")]
75pub struct UuidEditor {
76 widget: Widget,
77 value: Uuid,
78 text: Handle<UiNode>,
79 generate: Handle<UiNode>,
80}
81
82impl ConstructorProvider<UiNode, UserInterface> for UuidEditor {
83 fn constructor() -> GraphNodeConstructor<UiNode, UserInterface> {
84 GraphNodeConstructor::new::<Self>()
85 .with_variant("Uuid Editor", |ui| {
86 UuidEditorBuilder::new(WidgetBuilder::new().with_name("Uuid Editor"))
87 .build(&mut ui.build_ctx())
88 .into()
89 })
90 .with_group("Input")
91 }
92}
93
94define_widget_deref!(UuidEditor);
95
96uuid_provider!(UuidEditor = "667f7f48-2448-42da-91dd-cd743ca7117e");
97
98impl Control for UuidEditor {
99 fn handle_routed_message(&mut self, ui: &mut UserInterface, message: &mut UiMessage) {
100 self.widget.handle_routed_message(ui, message);
101
102 if message.destination() == self.handle && message.direction() == MessageDirection::ToWidget
103 {
104 if let Some(UuidEditorMessage::Value(value)) = message.data() {
105 if self.value != *value {
106 self.value = *value;
107 ui.send_message(message.reverse());
108
109 ui.send_message(TextMessage::text(
110 self.text,
111 MessageDirection::ToWidget,
112 value.to_string(),
113 ));
114 }
115 }
116 } else if message.destination() == self.generate {
117 if let Some(ButtonMessage::Click) = message.data() {
118 ui.send_message(UuidEditorMessage::value(
119 self.handle,
120 MessageDirection::ToWidget,
121 Uuid::new_v4(),
122 ));
123 }
124 }
125 }
126}
127
128pub struct UuidEditorBuilder {
130 widget_builder: WidgetBuilder,
131 value: Uuid,
132}
133
134impl UuidEditorBuilder {
135 pub fn new(widget_builder: WidgetBuilder) -> Self {
137 Self {
138 widget_builder,
139 value: Default::default(),
140 }
141 }
142
143 pub fn with_value(mut self, value: Uuid) -> Self {
145 self.value = value;
146 self
147 }
148
149 pub fn build(self, ctx: &mut BuildContext) -> Handle<UiNode> {
151 let text;
152 let generate;
153 let grid = GridBuilder::new(
154 WidgetBuilder::new()
155 .with_child({
156 text = TextBuilder::new(
157 WidgetBuilder::new()
158 .on_column(0)
159 .on_row(0)
160 .with_margin(Thickness::uniform(1.0))
161 .with_vertical_alignment(VerticalAlignment::Center),
162 )
163 .with_text(self.value.to_string())
164 .build(ctx);
165 text
166 })
167 .with_child({
168 generate = ButtonBuilder::new(
169 WidgetBuilder::new()
170 .on_column(1)
171 .on_row(0)
172 .with_width(24.0)
173 .with_margin(Thickness::uniform(1.0)),
174 )
175 .with_text("^/v")
176 .build(ctx);
177 generate
178 }),
179 )
180 .add_row(Row::stretch())
181 .add_column(Column::stretch())
182 .add_column(Column::auto())
183 .build(ctx);
184
185 let uuid_editor = UuidEditor {
186 widget: self.widget_builder.with_child(grid).build(ctx),
187 value: self.value,
188 text,
189 generate,
190 };
191
192 ctx.add_node(UiNode::new(uuid_editor))
193 }
194}
195
196#[cfg(test)]
197mod test {
198 use crate::uuid::UuidEditorBuilder;
199 use crate::{test::test_widget_deletion, widget::WidgetBuilder};
200
201 #[test]
202 fn test_deletion() {
203 test_widget_deletion(|ctx| UuidEditorBuilder::new(WidgetBuilder::new()).build(ctx));
204 }
205}