#![warn(missing_docs)]
use crate::{
core::{
algebra::Vector2, math::Rect, pool::Handle, reflect::prelude::*, type_traits::prelude::*,
visitor::prelude::*,
},
message::UiMessage,
widget::{Widget, WidgetBuilder},
BuildContext, Control, UiNode, UserInterface,
};
use fyrox_graph::constructor::{ConstructorProvider, GraphNodeConstructor};
use std::ops::{Deref, DerefMut};
#[derive(Default, Clone, Visit, Reflect, Debug, TypeUuidProvider, ComponentProvider)]
#[type_uuid(id = "6b843a36-53da-467b-b85e-2380fe891ca1")]
pub struct Canvas {
pub widget: Widget,
}
impl ConstructorProvider<UiNode, UserInterface> for Canvas {
fn constructor() -> GraphNodeConstructor<UiNode, UserInterface> {
GraphNodeConstructor::new::<Self>()
.with_variant("Canvas", |ui| {
CanvasBuilder::new(WidgetBuilder::new().with_name("Canvas"))
.build(&mut ui.build_ctx())
.into()
})
.with_group("Layout")
}
}
crate::define_widget_deref!(Canvas);
impl Control for Canvas {
fn measure_override(&self, ui: &UserInterface, _available_size: Vector2<f32>) -> Vector2<f32> {
let size_for_child = Vector2::new(f32::INFINITY, f32::INFINITY);
for child_handle in self.widget.children() {
ui.measure_node(*child_handle, size_for_child);
}
Vector2::default()
}
fn arrange_override(&self, ui: &UserInterface, final_size: Vector2<f32>) -> Vector2<f32> {
for &child_handle in self.widget.children() {
let child = ui.nodes.borrow(child_handle);
ui.arrange_node(
child_handle,
&Rect::new(
child.desired_local_position().x,
child.desired_local_position().y,
child.desired_size().x,
child.desired_size().y,
),
);
}
final_size
}
fn handle_routed_message(&mut self, ui: &mut UserInterface, message: &mut UiMessage) {
self.widget.handle_routed_message(ui, message);
}
}
pub struct CanvasBuilder {
widget_builder: WidgetBuilder,
}
impl CanvasBuilder {
pub fn new(widget_builder: WidgetBuilder) -> Self {
Self { widget_builder }
}
pub fn build(self, ctx: &mut BuildContext) -> Handle<UiNode> {
let canvas = Canvas {
widget: self.widget_builder.build(ctx),
};
ctx.add_node(UiNode::new(canvas))
}
}
#[cfg(test)]
mod test {
use crate::canvas::CanvasBuilder;
use crate::{test::test_widget_deletion, widget::WidgetBuilder};
#[test]
fn test_deletion() {
test_widget_deletion(|ctx| CanvasBuilder::new(WidgetBuilder::new()).build(ctx));
}
}