//! `cargo run --example sliders` //! //! Showcases the **Glass** effect on both axes of the slider widget. The //! horizontal `slider` at the top and the two vertical `vslider` pills //! below share the same composite surface — outer glow + four inset //! shadows (two `PlusLighter` light-catchers, one `Overlay` rim, one //! soft dark contact shadow) — over a translucent white-to-grey track //! and a flat cyan accent fill. //! //! Drag or tap anywhere inside the controls to change their values; Esc //! exits. //! //! NOTE: ltk is a Wayland layer-shell toolkit. This example requires a //! running Wayland compositor (e.g. sway, labwc, or a full desktop //! session). The Glass effect is rendered by the GPU (GLES2) backend — //! the software backend falls back to a flat fill. use ltk:: { App, Element, Color, Keysym, column, row, text, spacer, slider, vslider, }; #[ derive( Clone ) ] enum Msg { SetHue( f32 ), SetVolume( f32 ), SetBrightness( f32 ), } struct SlidersApp { hue: f32, volume: f32, brightness: f32, } impl SlidersApp { fn new() -> Self { Self { hue: 0.30, volume: 0.48, brightness: 0.92 } } } impl App for SlidersApp { type Message = Msg; fn view( &self ) -> Element { // Pill dimensions chosen so the Glass insets read at their // intended proportions. The insets (0.45–3.6 px offsets, // 0.9–13.5 px blur radii) are absolute, so smaller pills // produce relatively tighter highlights. const PILL_W: f32 = 80.0; const PILL_H: f32 = 176.0; // Track text against the active theme so switching to dark mode // (via `ltk::set_active_mode`) flips the labels automatically. let palette = ltk::theme_palette(); let primary = palette.text_primary; let secondary = palette.text_secondary; // Horizontal slider — claims its row's full width. let hue_slider = slider( self.hue ).on_change( Msg::SetHue ); // Two vertical pills. let brgt = vslider( self.brightness ).size( PILL_W, PILL_H ).on_change( Msg::SetBrightness ); let vol = vslider( self.volume ).size( PILL_W, PILL_H ).on_change( Msg::SetVolume ); let pills = row::() .spacing( 40.0 ) .padding( 0.0 ) .push( brgt ) .push( vol ); let pill_labels = row::() .spacing( 40.0 ) .padding( 0.0 ) .push( text( format!( "Brightness {:>3.0}%", self.brightness * 100.0 ) ) .size( 14.0 ) .color( primary ), ) .push( text( format!( "Volume {:>3.0}%", self.volume * 100.0 ) ) .size( 14.0 ) .color( primary ), ); column::() .padding( 32.0 ) .spacing( 16.0 ) .center_y( true ) .push( text( "ltk — Glass sliders, both axes" ) .size( 24.0 ) .color( primary ) .align_center(), ) .push( spacer() ) .push( text( format!( "Hue {:>3.0}%", self.hue * 100.0 ) ) .size( 14.0 ) .color( primary ), ) .push( hue_slider ) .push( spacer() ) .push( pills ) .push( pill_labels ) .push( spacer() ) .push( text( "Drag or tap inside a control · Esc = quit" ) .size( 12.0 ) .color( secondary ) .align_center(), ) .into() } fn update( &mut self, msg: Msg ) { match msg { Msg::SetHue( v ) => self.hue = v, Msg::SetVolume( v ) => self.volume = v, Msg::SetBrightness( v ) => self.brightness = v, } } fn on_key( &mut self, keysym: Keysym ) -> Option { if keysym == Keysym::Escape { std::process::exit( 0 ); } None } // Track the active theme's background so the Glass highlights and // the translucent track read correctly against it, and dark-mode // runs (via `ltk::set_active_mode(ThemeMode::Dark)`) flip // automatically. fn background_color( &self ) -> Color { ltk::theme_palette().bg } } fn main() { ltk::run( SlidersApp::new() ); }