1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
use std::borrow::Cow; use tuifw_screen_base::Side; use dep_obj::{dep_obj, DepTypeToken}; use once_cell::sync::{self}; use crate::base::{Widget, WidgetTree, WidgetObj, WidgetBehavior, ViewBuilderWidgetExt}; use crate::view::View; use crate::view::decorators::{ViewBuilderLabelDecoratorExt}; use crate::view::panels::{ViewBuilderDockPanelExt}; dep_obj! { #[derive(Debug)] pub struct Button become obj in Widget { content: Option<Widget> = None, } } static BUTTON_TOKEN: sync::Lazy<DepTypeToken<ButtonType>> = sync::Lazy::new(|| ButtonType::new_priv().expect("ButtonType builder locked") ); pub fn button_type() -> &'static ButtonType { BUTTON_TOKEN.ty() } impl Button { const BEHAVIOR: ButtonBehavior = ButtonBehavior; #[allow(clippy::new_ret_no_self)] pub fn new(tree: &mut WidgetTree) -> Widget { Widget::new(tree, Button::new_priv(&BUTTON_TOKEN)) } } impl WidgetObj for Button { fn behavior(&self) -> &'static dyn WidgetBehavior { &Self::BEHAVIOR } } struct ButtonBehavior; impl WidgetBehavior for ButtonBehavior { fn load(&self, tree: &mut WidgetTree, button: Widget, view: View) { let &content = button.obj_get(tree, button_type().content()); view.build(tree, |view| view .dock_panel(|panel| { panel .child(None, button, |layout| layout.dock(Some(Side::Left)), |view| view .label_decorator(|label| label.text(Cow::Borrowed("[ "))) ) .child(None, button, |layout| layout.dock(Some(Side::Right)), |view| view .label_decorator(|label| label.text(Cow::Borrowed(" ]"))) ) ; if let Some(content) = content { panel.child(None, content, |layout| layout, |view| view.widget(content)); } panel }) ); } }