use kahlo::math::PixelSideOffsets; use patina::{ layout::SizePolicy, prelude::*, ui::{UIControlMsg, UIHandle}, widget, }; struct FormWindow { root: widget::Frame, } impl FormWindow { fn new(uih: &mut UIHandle) -> Self { let mut group = widget::FormGroup::new(uih); group .layout_node_mut() .set_height_policy(SizePolicy::fixed(0)); group.set_label_margin(PixelSideOffsets::new(0, 10, 0, 10)); group.add_widget( "button", widget::Button::new(uih).with_label("engage").boxed(), ); group.add_widget( "button 2", widget::Button::new(uih).with_label("engage").boxed(), ); group.add_widget( "button 3", widget::Button::new(uih).with_label("engage").boxed(), ); group.add_widget( "button 4 with longer description", widget::Button::new(uih).with_label("engage").boxed(), ); Self { root: widget::Frame::wrap_widget(group), } } } impl Component for FormWindow { type ParentMsg = UIControlMsg; type Msg = (); fn process(&mut self, _msg: Self::Msg) -> Vec { let mut out = String::new(); patina::layout::dump_node_tree(self.root.layout_node(), &mut out); std::fs::write("patina-form-example.layout_tree", out).expect("couldn't dump node tree"); vec![UIControlMsg::Terminate] } } impl WindowComponent for FormWindow { fn map_window_event(&self, we: patina::window::WindowEvent) -> Option { match we { patina::window::WindowEvent::CloseRequested => Some(()), _ => None, } } type RootWidget = widget::Frame; fn root_widget(&self) -> &Self::RootWidget { &self.root } fn root_widget_mut(&mut self) -> &mut Self::RootWidget { &mut self.root } } fn main() { patina::ui::make_opinionated_ui(FormWindow::new).run(); }