1use std::convert::{TryFrom, TryInto};
2
3use lazy_static::lazy_static;
4use nsys::geometry;
5use nsys::math::Vector2;
6
7use crate::prelude::*;
8
9use super::set_layout;
10
11pub use self::builder::FreeBuilder as Builder;
12
13lazy_static!{
18 pub static ref CONTROLS : Controls = controls::Builder::new()
19 .buttons ({
20 let mut v : Vec <controls::Button> = vec![
21 controls::button::Builtin::FrameFreeMoveRight,
22 controls::button::Builtin::FrameFreeMoveLeft,
23 controls::button::Builtin::FrameFreeMoveUp,
24 controls::button::Builtin::FrameFreeMoveDown,
25 controls::button::Builtin::FrameFreeGrowWidth,
26 controls::button::Builtin::FrameFreeShrinkWidth,
27 controls::button::Builtin::FrameFreeGrowHeight,
28 controls::button::Builtin::FrameFreeShrinkHeight
29 ].into_iter().map (Into::into).collect();
30 v.extend (super::CONTROLS.buttons.iter().cloned());
31 v.into()
32 })
33 .build();
34}
35
36pub fn move_right (
40 _ : &controls::button::Release,
41 elements : &Tree <Element>,
42 node_id : &NodeId,
43 action_buffer : &mut Vec <(NodeId, Action)>
44) {
45 log::trace!("move_right...");
46 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
47 let coord_kind_override = Some (canvas.coordinates.kind());
48 let layout = {
49 use controller::component::Layout;
50 let (mut free, area) = layout.variant.clone().try_into().unwrap();
51 free.offset_move_right();
52 Layout { variant: (free, area).into(), .. layout.clone() }
53 };
54 set_layout (elements, node_id, layout, coord_kind_override, action_buffer);
55 log::trace!("...move_right");
56}
57
58pub fn move_left (
62 _ : &controls::button::Release,
63 elements : &Tree <Element>,
64 node_id : &NodeId,
65 action_buffer : &mut Vec <(NodeId, Action)>
66) {
67 log::trace!("move_left...");
68 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
69 let coordinate_kind = Some (canvas.coordinates.kind());
70 let layout = {
71 use controller::component::Layout;
72 let (mut free, area) = layout.variant.clone().try_into().unwrap();
73 free.offset_move_left();
74 Layout { variant: (free, area).into(), .. layout.clone() }
75 };
76 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
77 log::trace!("...move_left");
78}
79
80pub fn move_up (
84 _ : &controls::button::Release,
85 elements : &Tree <Element>,
86 node_id : &NodeId,
87 action_buffer : &mut Vec <(NodeId, Action)>
88) {
89 log::trace!("move_up...");
90 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
91 let coordinate_kind = Some (canvas.coordinates.kind());
92 let layout = {
93 use controller::component::Layout;
94 let (mut free, area) = layout.variant.clone().try_into().unwrap();
95 free.offset_move_up();
96 Layout { variant: (free, area).into(), .. layout.clone() }
97 };
98 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
99 log::trace!("...move_up");
100}
101
102pub fn move_down (
106 _ : &controls::button::Release,
107 elements : &Tree <Element>,
108 node_id : &NodeId,
109 action_buffer : &mut Vec <(NodeId, Action)>
110) {
111 log::trace!("move_down...");
112 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
113 let coordinate_kind = Some (canvas.coordinates.kind());
114 let layout = {
115 use controller::component::Layout;
116 let (mut free, area) = layout.variant.clone().try_into().unwrap();
117 free.offset_move_down();
118 Layout { variant: (free, area).into(), .. layout.clone() }
119 };
120 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
121 log::trace!("...move_down");
122}
123
124pub fn grow_width (
128 _ : &controls::button::Release,
129 elements : &Tree <Element>,
130 node_id : &NodeId,
131 action_buffer : &mut Vec <(NodeId, Action)>
132) {
133 log::trace!("grow_width...");
134 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
135 let coordinate_kind = Some (canvas.coordinates.kind());
136 let layout = {
137 use controller::component::Layout;
138 let (mut free, area) = layout.variant.clone().try_into().unwrap();
139 free.size_grow_width();
140 Layout { variant: (free, area).into(), .. layout.clone() }
141 };
142 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
143 log::trace!("...grow_width");
144}
145
146pub fn shrink_width (
150 _ : &controls::button::Release,
151 elements : &Tree <Element>,
152 node_id : &NodeId,
153 action_buffer : &mut Vec <(NodeId, Action)>
154) {
155 log::trace!("shrink_width...");
156 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
157 let coordinate_kind = Some (canvas.coordinates.kind());
158 let layout = {
159 use controller::component::Layout;
160 let (mut free, area) = layout.variant.clone().try_into().unwrap();
161 free.size_shrink_width();
162 Layout { variant: (free, area).into(), .. layout.clone() }
163 };
164 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
165 log::trace!("...shrink_width");
166}
167
168pub fn grow_height (
172 _ : &controls::button::Release,
173 elements : &Tree <Element>,
174 node_id : &NodeId,
175 action_buffer : &mut Vec <(NodeId, Action)>
176) {
177 log::trace!("grow_height...");
178 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
179 let coordinate_kind = Some (canvas.coordinates.kind());
180 let layout = {
181 use controller::component::Layout;
182 let (mut free, area) = layout.variant.clone().try_into().unwrap();
183 free.size_grow_height();
184 Layout { variant: (free, area).into(), .. layout.clone() }
185 };
186 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
187 log::trace!("...grow_height");
188}
189
190pub fn shrink_height (
194 _ : &controls::button::Release,
195 elements : &Tree <Element>,
196 node_id : &NodeId,
197 action_buffer : &mut Vec <(NodeId, Action)>
198) {
199 log::trace!("shrink_height...");
200 let Widget (layout, _, canvas) = Frame::try_get (elements, node_id).unwrap();
201 let coordinate_kind = Some (canvas.coordinates.kind());
202 let layout = {
203 use controller::component::Layout;
204 let (mut free, area) = layout.variant.clone().try_into().unwrap();
205 free.size_shrink_height();
206 Layout { variant: (free, area).into(), .. layout.clone() }
207 };
208 set_layout (elements, node_id, layout, coordinate_kind, action_buffer);
209 log::trace!("...shrink_height");
210}
211
212pub fn rearrange_absolute (
219 elements : &Tree <Element>,
220 parent_id : &NodeId,
221 anchor : controller::Alignment,
222 offset_hv : (i32, i32),
223 orientation : controller::Orientation,
224 spacing : u32,
225 reverse : bool
226) -> Vec <(NodeId, Action)> {
227 use controller::{offset, size, Offset, Orientation, Size};
228 use controller::component::{layout, Layout};
229 log::trace!("rearrange_absolute...");
230 let mut out = vec![];
231 let children_ids = elements.children_ids (&parent_id).unwrap();
232 match orientation {
233 Orientation::Horizontal => {
234 let (mut horizontal, vertical) = offset_hv;
235 for child_id in children_ids {
236 if let Ok (Widget (layout, _, canvas)) =
237 Frame::try_get (elements, child_id)
238 {
239 match layout.variant {
240 layout::Variant::Free (free@layout::Free {
241 offset: Offset { horizontal: offset::Signed::Absolute (_), .. },
242 size: Size { width: size::Unsigned::Absolute (_), .. },
243 ..
244 }, ref area) => {
245 let coordinate_kind = Some (canvas.coordinates.kind());
246 let layout = {
247 let offset = {
248 let horizontal = horizontal.into();
249 let vertical = vertical.into();
250 Offset { horizontal, vertical }
251 };
252 let size = {
253 let size = free.size.clone();
254 let w = u32::try_from (size.width).unwrap();
255 let next = (w + spacing) as i32;
256 if reverse {
257 horizontal -= next;
258 } else {
259 horizontal += next;
260 }
261 size
262 };
263 let free = layout::Free { anchor, offset, size };
264 Layout { variant: (free, area.clone()).into(), .. layout.clone() }
265 };
266 set_layout (elements, &child_id, layout, coordinate_kind, &mut out);
267 }
268 _ => {}
269 }
270 }
271 }
272 }
273 Orientation::Vertical => {
274 let (horizontal, mut vertical) = offset_hv;
275 for child_id in children_ids {
276 if let Ok (Widget (layout, _, canvas)) =
277 Frame::try_get (elements, child_id)
278 {
279 match layout.variant {
280 layout::Variant::Free (free@layout::Free {
281 offset: Offset { vertical: offset::Signed::Absolute (_), .. },
282 size: Size { height: size::Unsigned::Absolute (_), .. },
283 ..
284 }, ref area) => {
285 let coordinate_kind = Some (canvas.coordinates.kind());
286 let layout = {
287 let offset = {
288 let horizontal = horizontal.into();
289 let vertical = vertical.into();
290 Offset { horizontal, vertical }
291 };
292 let size = {
293 let size = free.size.clone();
294 let h = u32::try_from (size.height).unwrap();
295 let next = (h + spacing) as i32;
296 if reverse {
297 vertical -= next;
298 } else {
299 vertical += next;
300 }
301 size
302 };
303 let free = layout::Free { anchor, offset, size };
304 Layout { variant: (free, area.clone()).into(), .. layout.clone() }
305 };
306 set_layout (elements, &child_id, layout, coordinate_kind, &mut out);
307 }
308 _ => {}
309 }
310 }
311 }
312 }
313 }
314 log::trace!("...rearrange_absolute");
315 out
316}
317
318pub (crate) fn coordinates (
325 parent_canvas : &view::component::Canvas,
326 layout : &controller::component::layout::Free,
327 area : &controller::Area,
328 coord_kind_override : Option <view::coordinates::Kind>
329) -> view::Coordinates {
330 log::trace!("coordinates...");
331 let controller::component::layout::Free { anchor, offset, size } = layout;
332 let parent_coordinates = match area {
333 controller::Area::Exterior => parent_canvas.coordinates,
334 controller::Area::Interior => parent_canvas.body_coordinates()
335 };
336 let dimensions = dimensions (&parent_coordinates.dimensions(), size,
337 coord_kind_override);
338 let position = position (&parent_coordinates, &dimensions, anchor, offset,
339 coord_kind_override);
340 let out = (position, dimensions).try_into().unwrap();
341 log::trace!("...coordinates");
342 out
343}
344
345#[inline]
357fn dimensions (
358 parent_dimensions : &view::Dimensions,
359 size : &controller::Size,
360 coord_kind_override : Option <view::coordinates::Kind>
361) -> view::Dimensions {
362 use controller::size;
363 use view::{coordinates, dimensions, Dimensions};
364 log::trace!("dimensions...");
365 let same_as_parent = || match parent_dimensions {
366 Dimensions::Tile (dimensions) => {
367 let rows = match size.height {
368 size::Unsigned::Absolute (height) => height,
369 size::Unsigned::Relative (height) =>
370 std::cmp::max (1, (dimensions.rows() as f32 * *height) as u32)
371 };
372 let columns = match size.width {
373 size::Unsigned::Absolute (width) => width,
374 size::Unsigned::Relative (width) =>
375 std::cmp::max (1, (dimensions.columns() as f32 * *width) as u32)
376 };
377 Dimensions::from (dimensions::Tile::from (Vector2::new (rows, columns)))
378 }
379 Dimensions::Pixel (dimensions) => {
380 let width = match size.width {
381 size::Unsigned::Absolute (width) => width,
382 size::Unsigned::Relative (width) =>
383 std::cmp::max (1, (dimensions.width() as f32 * *width) as u32)
384 };
385 let height = match size.height {
386 size::Unsigned::Absolute (height) => height,
387 size::Unsigned::Relative (height) =>
388 std::cmp::max (1, (dimensions.height() as f32 * *height) as u32)
389 };
390 Dimensions::from (dimensions::Pixel::from (Vector2::new (width, height)))
391 }
392 };
393 let out = if let Some (kind) = coord_kind_override {
394 match parent_dimensions {
395 Dimensions::Tile (_dimensions) =>
396 if kind == coordinates::Kind::Tile {
397 same_as_parent()
398 } else {
399 unimplemented!("TODO: pixel dimensions with tile dimension parent")
400 }
401 Dimensions::Pixel (dimensions) =>
402 if kind == coordinates::Kind::Pixel {
403 same_as_parent()
404 } else {
405 let [tile_width, tile_height] = *coordinates::TILE_WH;
406 let rows = match size.height {
407 size::Unsigned::Absolute (height) => height,
408 size::Unsigned::Relative (height) => {
409 let parent_rows = dimensions.height() / tile_height as u32;
410 std::cmp::max (1, (parent_rows as f32 * *height) as u32)
411 }
412 };
413 let columns = match size.width {
414 size::Unsigned::Absolute (width) => width,
415 size::Unsigned::Relative (width) => {
416 let parent_columns = dimensions.width() / tile_width as u32;
417 std::cmp::max (1, (parent_columns as f32 * *width) as u32)
418 }
419 };
420 Dimensions::from (dimensions::Tile::from (Vector2::new (rows, columns)))
421 }
422 }
423 } else {
424 same_as_parent()
425 };
426 log::trace!("...dimensions");
427 out
428}
429
430fn position (
436 parent_coordinates : &view::Coordinates,
437 dimensions : &view::Dimensions,
438 anchor : &controller::Alignment,
439 offset : &controller::Offset,
440 coord_kind_override : Option <view::coordinates::Kind>
441) -> view::Position {
442 use controller::{alignment, offset};
443 use view::{coordinates, dimensions, position, Coordinates};
444 log::trace!("position...");
445 let same_as_parent = || match parent_coordinates {
446 Coordinates::Tile (parent_position, parent_dimensions) => {
447 let dimensions = dimensions::Tile::try_from (*dimensions).unwrap();
448 let row = match offset.vertical {
449 offset::Signed::Absolute (vertical) => match anchor.vertical {
450 alignment::Vertical::Top => vertical,
451 alignment::Vertical::Middle =>
452 parent_dimensions.rows() as i32/2 - dimensions.rows() as i32/2
453 - vertical,
454 alignment::Vertical::Bottom =>
455 parent_dimensions.rows() as i32 - dimensions.rows() as i32
456 - vertical
457 }
458 offset::Signed::Relative (vertical) => {
459 let absolute_offset = (*vertical * parent_dimensions.rows() as f32)
460 as i32;
461 match anchor.vertical {
462 alignment::Vertical::Top => absolute_offset,
463 alignment::Vertical::Middle =>
464 parent_dimensions.rows() as i32/2 - dimensions.rows() as i32/2
465 - absolute_offset,
466 alignment::Vertical::Bottom =>
467 parent_dimensions.rows() as i32 - dimensions.rows() as i32
468 - absolute_offset
469 }
470 }
471 };
472 let column = match offset.horizontal {
473 offset::Signed::Absolute (horizontal) => match anchor.horizontal {
474 alignment::Horizontal::Left => horizontal,
475 alignment::Horizontal::Center =>
476 parent_dimensions.columns() as i32/2 - dimensions.columns() as i32/2
477 + horizontal,
478 alignment::Horizontal::Right =>
479 parent_dimensions.columns() as i32 - dimensions.columns() as i32
480 - horizontal
481 }
482 offset::Signed::Relative (horizontal) => {
483 let absolute_offset =
484 (*horizontal * parent_dimensions.columns() as f32) as i32;
485 match anchor.horizontal {
486 alignment::Horizontal::Left => absolute_offset,
487 alignment::Horizontal::Center =>
488 parent_dimensions.columns() as i32/2
489 - dimensions.columns() as i32/2 + absolute_offset,
490 alignment::Horizontal::Right =>
491 parent_dimensions.columns() as i32 - dimensions.columns() as i32
492 - absolute_offset
493 }
494 }
495 };
496 position::Tile::from (
497 parent_position.position_rc + Vector2::new (row, column)
498 ).into()
499 }
500 Coordinates::Pixel (parent_position, parent_dimensions) => {
501 let dimensions = dimensions::Pixel::try_from (*dimensions).unwrap();
502 let y = match offset.vertical {
503 offset::Signed::Absolute (vertical) => match anchor.vertical {
504 alignment::Vertical::Bottom => vertical,
505 alignment::Vertical::Middle =>
506 parent_dimensions.height() as i32/2 - dimensions.height() as i32/2
507 + vertical,
508 alignment::Vertical::Top =>
509 parent_dimensions.height() as i32 - dimensions.height() as i32
510 - vertical
511 }
512 offset::Signed::Relative (vertical) => {
513 let absolute_offset =
514 (*vertical * parent_dimensions.height() as f32) as i32;
515 match anchor.vertical {
516 alignment::Vertical::Bottom =>
517 absolute_offset,
518 alignment::Vertical::Middle =>
519 parent_dimensions.height() as i32/2
520 - dimensions.height() as i32/2 + absolute_offset,
521 alignment::Vertical::Top =>
522 parent_dimensions.height() as i32 - dimensions.height() as i32
523 - absolute_offset
524 }
525 }
526 };
527 let x = match offset.horizontal {
528 offset::Signed::Absolute (horizontal) => match anchor.horizontal {
529 alignment::Horizontal::Left => horizontal,
530 alignment::Horizontal::Center =>
531 parent_dimensions.width() as i32/2
532 - dimensions.width() as i32/2 + horizontal,
533 alignment::Horizontal::Right =>
534 parent_dimensions.width() as i32 - dimensions.width() as i32
535 - horizontal
536 }
537 offset::Signed::Relative (horizontal) => {
538 let absolute_offset = (*horizontal * parent_dimensions.width() as f32)
539 as i32;
540 match anchor.horizontal {
541 alignment::Horizontal::Left => absolute_offset,
542 alignment::Horizontal::Center =>
543 parent_dimensions.width() as i32/2
544 - dimensions.width() as i32/2 + absolute_offset,
545 alignment::Horizontal::Right =>
546 parent_dimensions.width() as i32 - dimensions.width() as i32
547 - absolute_offset
548 }
549 }
550 };
551 position::Pixel::from (parent_position.position_xy + Vector2::new (x, y))
552 .into()
553 }
554 };
555 let out = if let Some (kind) = coord_kind_override {
556 match parent_coordinates.kind() {
557 coordinates::Kind::Tile => if kind == coordinates::Kind::Tile {
558 same_as_parent()
559 } else {
560 unimplemented!("TODO: pixel position with tile position parent")
561 }
562 coordinates::Kind::Pixel => if kind == coordinates::Kind::Pixel {
563 same_as_parent()
564 } else {
565 let parent_aabb = geometry::integer::Aabb2::from (
567 parent_coordinates.clone());
568 let parent_aabb_tiles = coordinates::pixel_to_tile_aabb (parent_aabb);
569 let [parent_row, parent_column] = parent_aabb_tiles.min().0
570 .into_array();
571 let parent_columns = parent_aabb_tiles.width();
572 let parent_rows = parent_aabb_tiles.height();
573 let dimensions = dimensions::Tile::try_from (*dimensions).unwrap();
574 let row = match offset.vertical {
575 offset::Signed::Absolute (vertical) => match anchor.vertical {
576 alignment::Vertical::Top => vertical,
577 alignment::Vertical::Middle =>
578 parent_rows as i32/2 - dimensions.rows() as i32/2
579 - vertical,
580 alignment::Vertical::Bottom =>
581 parent_rows as i32 - dimensions.rows() as i32
582 - vertical
583 }
584 offset::Signed::Relative (vertical) => {
585 let absolute_offset = (*vertical * parent_rows as f32)
586 as i32;
587 match anchor.vertical {
588 alignment::Vertical::Top => absolute_offset,
589 alignment::Vertical::Middle =>
590 parent_rows as i32/2 - dimensions.rows() as i32/2
591 - absolute_offset,
592 alignment::Vertical::Bottom =>
593 parent_rows as i32 - dimensions.rows() as i32
594 - absolute_offset
595 }
596 }
597 };
598 let column = match offset.horizontal {
599 offset::Signed::Absolute (horizontal) => match anchor.horizontal {
600 alignment::Horizontal::Left => horizontal,
601 alignment::Horizontal::Center =>
602 parent_columns as i32/2 - dimensions.columns() as i32/2
603 + horizontal,
604 alignment::Horizontal::Right =>
605 parent_columns as i32 - dimensions.columns() as i32 - horizontal
606 }
607 offset::Signed::Relative (horizontal) => {
608 let absolute_offset =
609 (*horizontal * parent_columns as f32) as i32;
610 match anchor.horizontal {
611 alignment::Horizontal::Left => absolute_offset,
612 alignment::Horizontal::Center =>
613 parent_columns as i32/2
614 - dimensions.columns() as i32/2 + absolute_offset,
615 alignment::Horizontal::Right =>
616 parent_columns as i32 - dimensions.columns() as i32
617 - absolute_offset
618 }
619 }
620 };
621 position::Tile::new_rc (parent_row + row, parent_column + column)
622 .into()
623 }
624 }
625 } else {
626 same_as_parent()
627 };
628 log::trace!("...position");
629 out
630}
631
632mod builder {
637 use derive_builder::Builder;
638 use crate::prelude::*;
639
640 #[derive(Builder)]
641 #[builder(pattern="owned", build_fn(private), setter(strip_option))]
642 pub struct Free <'a, A : Application> {
643 elements : &'a Tree <Element>,
644 parent_id : &'a NodeId,
645 #[builder(default)]
646 appearances : controller::Appearances,
647 #[builder(default)]
648 area : controller::Area,
649 #[builder(default)]
650 bindings : Option <&'a controller::Bindings <A>>,
651 #[builder(default)]
652 border : Option <view::Border>,
653 #[builder(default)]
654 clear_color : canvas::ClearColor,
655 #[builder(default)]
656 coord_kind_override : Option <view::coordinates::Kind>,
657 #[builder(default)]
658 disabled : bool,
659 #[builder(default)]
660 layout : controller::component::layout::Free,
661 #[builder(default)]
662 orientation : (controller::Orientation, controller::Area)
663 }
664
665 impl <'a, A : Application> FreeBuilder <'a, A> {
666 pub fn new (elements : &'a Tree <Element>, parent_id : &'a NodeId) -> Self {
667 FreeBuilder {
668 elements: Some (elements),
669 parent_id: Some (parent_id),
670 appearances: None,
671 area: None,
672 bindings: None,
673 border: None,
674 clear_color: None,
675 coord_kind_override: None,
676 disabled: None,
677 layout: None,
678 orientation: None
679 }
680 }
681 }
682
683 impl <'a, A : Application> BuildElement for FreeBuilder <'a, A> {
684 fn build_element (self) -> Element {
692 log::trace!("build element...");
693 let Free {
694 elements, parent_id, appearances, area, bindings, border, clear_color,
695 coord_kind_override, layout, orientation, disabled
696 } = self.build()
697 .map_err(|err| log::error!("frame free builder error: {:?}", err))
698 .unwrap();
699 let bindings_empty = Bindings::empty();
700 let bindings = bindings.unwrap_or(&bindings_empty)
701 .get_bindings (&super::CONTROLS);
702 let Widget (_, _, parent_canvas) = Frame::try_get (elements, parent_id)
703 .unwrap();
704 let parent_node = elements.get (parent_id).unwrap();
705 let mut focus_top = true;
706 if let Some (first_child_id) = parent_node.children().first() {
707 if Menu::try_get (elements, first_child_id).is_ok() {
708 focus_top = false;
709 }
710 }
711 let controller = {
712 let mut controller = Controller::with_bindings (&bindings);
713 controller.component = Layout {
714 orientation, variant: (layout.clone(), area.clone()).into(),
715 }.into();
716 controller.focus_top = focus_top;
717 controller.appearances = appearances;
718 controller
719 };
720 let view = {
721 let coordinates = super::coordinates (
722 &parent_canvas, &layout, &area, coord_kind_override);
723 let appearance = controller.get_appearance().clone();
724 let component = Canvas { coordinates, clear_color, border }.into();
725 View { component, appearance, .. View::default() }
726 };
727 let mut frame =
728 Element::new ("Frame".to_string(), controller, Model::default(), view);
729 if parent_node.data().controller.state == State::Disabled || disabled {
730 frame.disable()
731 }
732 log::trace!("...build element");
733 frame
734 }
735 }
736}