//! `cargo run --example pickers` //! //! Showcases the four composition widgets added in this pass: //! `notebook` (paginated tabs with a content area), `date_picker`, //! `time_picker`, and `color_picker`. Each picker lives on its own //! notebook page so the example doubles as a notebook demo. //! //! Esc exits. use ltk:: { App, Element, Color, Keysym, column, text, scroll, notebook, date_picker, time_picker, color_picker, Date, Time, }; #[ derive( Clone, Debug ) ] enum Msg { SelectTab( usize ), DateChanged( Date ), DateView( i32, u8 ), TimeChanged( Time ), ColorChanged( Color ), } struct PickerApp { tab: usize, date: Date, view_year: i32, view_month: u8, time: Time, color: Color, } impl PickerApp { fn new() -> Self { let today = Date::new( 2026, 5, 2 ); Self { tab: 0, date: today, view_year: today.year, view_month: today.month, time: Time::new( 9, 30 ), color: Color::hex( 0x14, 0xB8, 0xA6 ), } } fn date_page( &self ) -> Element { let primary = ltk::theme_palette().text_primary; let summary = format!( "Selected: {}-{:02}-{:02}", self.date.year, self.date.month, self.date.day, ); column::() .padding( 0.0 ) .spacing( 16.0 ) .push( text( summary ).size( 14.0 ).color( primary ) ) .push( date_picker( self.date ) .view( self.view_year, self.view_month ) .today( Date::new( 2026, 5, 2 ) ) .on_change( Msg::DateChanged ) .on_navigate( Msg::DateView ) ) .into() } fn time_page( &self ) -> Element { let primary = ltk::theme_palette().text_primary; let summary = format!( "Selected: {:02}:{:02}", self.time.hour, self.time.minute, ); column::() .padding( 0.0 ) .spacing( 16.0 ) .push( text( summary ).size( 14.0 ).color( primary ) ) .push( time_picker( self.time ) .minute_step( 1 ) .twelve_hour( true ) .on_change( Msg::TimeChanged ) ) .into() } fn color_page( &self ) -> Element { let primary = ltk::theme_palette().text_primary; let summary = format!( "R={:.2} G={:.2} B={:.2} A={:.2}", self.color.r, self.color.g, self.color.b, self.color.a, ); column::() .padding( 0.0 ) .spacing( 16.0 ) .push( text( summary ).size( 14.0 ).color( primary ) ) .push( color_picker( self.color ) .show_alpha( true ) .on_change( Msg::ColorChanged ) ) .into() } } impl App for PickerApp { type Message = Msg; fn view( &self ) -> Element { let header = text( "ltk pickers" ) .size( 24.0 ) .color( ltk::theme_palette().text_primary ) .align_center(); let body = column::() .padding( 24.0 ) .spacing( 16.0 ) .push( header ) .push( notebook::() .page( "Date", self.date_page() ) .page( "Time", self.time_page() ) .page( "Color", self.color_page() ) .selected( self.tab ) .on_select( Msg::SelectTab ) ); // Wrap in a scroll so the calendar's 6×7 grid fits even on // modest window heights. scroll( body ).into() } fn update( &mut self, msg: Msg ) { match msg { Msg::SelectTab( i ) => self.tab = i, Msg::DateChanged( d ) => { self.date = d; self.view_year = d.year; self.view_month = d.month; } Msg::DateView( y, m ) => { self.view_year = y; self.view_month = m; } Msg::TimeChanged( t ) => self.time = t, Msg::ColorChanged( c ) => self.color = c, } } fn on_key( &mut self, keysym: Keysym ) -> Option { if keysym == Keysym::Escape { std::process::exit( 0 ); } None } } fn main() { ltk::run( PickerApp::new() ); }