Files
ltk/examples/sliders.rs

156 lines
3.7 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! `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<Msg>
{
// Pill dimensions chosen so the Glass insets read at their
// intended proportions. The insets (0.453.6 px offsets,
// 0.913.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::<Msg>()
.spacing( 40.0 )
.padding( 0.0 )
.push( brgt )
.push( vol );
let pill_labels = row::<Msg>()
.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::<Msg>()
.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<Msg>
{
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() );
}