use std::rc::Rc; use ruin_ui::{CursorIcon, Edges, Element, RoutedPointerEvent}; use crate::context::allocate_element_id; use crate::input::PressHandler; use crate::primitives::ContainerProps; use crate::surfaces; use crate::text_style::{pop_text_style, push_text_style}; use crate::view::{Children, View}; pub struct ButtonBuilder { pub(crate) props: ContainerProps, pub(crate) on_press: Option, } pub fn button() -> ButtonBuilder { ButtonBuilder { props: ContainerProps::new( Element::column() .padding(Edges::symmetric(14.0, 10.0)) .background(surfaces::interactive()) .corner_radius(10.0) .cursor(CursorIcon::Pointer) .focusable(true), ), on_press: None, } } impl ButtonBuilder { impl_props_methods!(); pub fn shadow(mut self, shadow: impl crate::converters::IntoShadow) -> Self { self.props = self.props.shadow(shadow); self } pub fn on_press(mut self, handler: impl Fn(&RoutedPointerEvent) + 'static) -> Self { self.on_press = Some(Rc::new(handler)); self } pub fn text_style(mut self, style: crate::text_style::PartialTextStyle) -> Self { self.props = self.props.text_style(style); self } pub fn children(mut self, children: impl Children) -> View { let id = allocate_element_id(); self.props.element = self.props.element.id(id); if let Some(widget_ref) = &self.props.widget_ref { let _ = widget_ref.set(Some(id)); } let had_style = self.props.partial_text_style.is_some(); if let Some(style) = self.props.partial_text_style.take() { push_text_style(style); } let children_views = children.into_views(); if had_style { pop_text_style(); } let view = View::from_container(self.props.element, children_views); match self.on_press { Some(handler) => view.with_press_handler(id, handler), None => view, } } }