iced-yoda/examples/table/src/main.rs

230 lines
6.9 KiB
Rust
Raw Normal View History

2025-07-15 05:28:33 +02:00
use iced::font;
use iced::time::{Duration, hours, minutes};
use iced::widget::{
center, center_x, column, container, row, scrollable, slider, table, text,
tooltip,
};
use iced::{Center, Element, Fill, Font};
2025-07-15 05:28:33 +02:00
pub fn main() -> iced::Result {
iced::application(Table::new, Table::update, Table::view).run()
}
struct Table {
events: Vec<Event>,
padding: (f32, f32),
separator: (f32, f32),
2025-07-15 05:28:33 +02:00
}
#[derive(Debug, Clone)]
enum Message {
PaddingChanged(f32, f32),
SeparatorChanged(f32, f32),
}
2025-07-15 05:28:33 +02:00
impl Table {
fn new() -> Self {
Self {
events: Event::list(),
padding: (10.0, 5.0),
separator: (1.0, 1.0),
2025-07-15 05:28:33 +02:00
}
}
fn update(&mut self, message: Message) {
match message {
Message::PaddingChanged(x, y) => self.padding = (x, y),
Message::SeparatorChanged(x, y) => self.separator = (x, y),
}
2025-07-15 05:28:33 +02:00
}
fn view(&self) -> Element<'_, Message> {
let table = {
let bold = |header| {
text(header).font(Font {
weight: font::Weight::Bold,
..Font::DEFAULT
})
};
let columns = [
table::column(bold("Name"), |event: &Event| {
2025-07-15 05:28:33 +02:00
text(&event.name).width(Fill)
}),
table::column(bold("Time"), |event: &Event| {
text!("{} min", event.duration.as_secs() / 60)
}),
table::column(bold("Price"), |event: &Event| {
if event.price > 0.0 {
text!("${:.2}", event.price)
} else {
text("Free")
}
}),
table::column(bold("Rating"), |event: &Event| {
text!("{:.2}", event.rating)
}),
];
table(columns, &self.events)
.width(640)
.padding_x(self.padding.0)
.padding_y(self.padding.1)
.separator_x(self.separator.0)
.separator_y(self.separator.1)
};
let controls = {
let labeled_slider =
|label,
range: std::ops::RangeInclusive<f32>,
(x, y),
on_change: fn(f32, f32) -> Message| {
row![
text(label).font(Font::MONOSPACE).size(14).width(200),
tooltip(
slider(range.clone(), x, move |x| on_change(x, y)),
text!("{x:.0}px").font(Font::MONOSPACE).size(10),
tooltip::Position::Left
),
tooltip(
slider(range, y, move |y| on_change(x, y)),
text!("{y:.0}px").font(Font::MONOSPACE).size(10),
tooltip::Position::Right
),
]
.spacing(10)
.align_y(Center)
};
2025-07-15 05:28:33 +02:00
column![
labeled_slider(
"Padding",
0.0..=30.0,
self.padding,
Message::PaddingChanged
),
labeled_slider(
"Separator",
0.0..=5.0,
self.separator,
Message::SeparatorChanged
)
]
.spacing(10)
.width(640)
2025-07-15 05:28:33 +02:00
};
column![
center(scrollable(table).spacing(10)).padding(10),
center_x(controls).padding(10).style(container::dark)
]
.into()
2025-07-15 05:28:33 +02:00
}
}
struct Event {
name: String,
duration: Duration,
price: f32,
rating: f32,
}
impl Event {
fn list() -> Vec<Self> {
vec![
Event {
name: "Get lost in a hacker bookstore".to_owned(),
duration: hours(2),
price: 0.0,
rating: 4.9,
},
Event {
name: "Buy vintage synth at Noisebridge flea market".to_owned(),
duration: hours(1),
price: 150.0,
rating: 4.8,
},
Event {
name: "Eat a questionable hot dog at 2AM".to_owned(),
duration: minutes(20),
price: 5.0,
rating: 1.7,
},
Event {
name: "Ride the MUNI for the story".to_owned(),
duration: minutes(60),
price: 3.0,
rating: 4.1,
},
Event {
name: "Scream into the void from Twin Peaks".to_owned(),
duration: minutes(40),
price: 0.0,
rating: 4.9,
},
Event {
name: "Buy overpriced coffee and feel things".to_owned(),
duration: minutes(25),
price: 6.5,
rating: 4.5,
},
Event {
name: "Attend an underground robot poetry slam".to_owned(),
duration: hours(1),
price: 12.0,
rating: 4.8,
},
Event {
name: "Browse cursed tech at a retro computer fair".to_owned(),
duration: hours(2),
price: 10.0,
rating: 4.7,
},
Event {
name: "Try to order at a secret ramen place with no sign"
.to_owned(),
duration: minutes(50),
price: 14.0,
rating: 4.6,
},
Event {
name: "Join a spontaneous rooftop drone rave".to_owned(),
duration: hours(3),
price: 0.0,
rating: 4.9,
},
Event {
name: "Sketch a stranger at Dolores Park".to_owned(),
duration: minutes(45),
price: 0.0,
rating: 4.4,
},
Event {
name: "Visit the Museum of Obsolete APIs".to_owned(),
duration: hours(1),
price: 9.99,
rating: 4.2,
},
Event {
name: "Chase the last working payphone".to_owned(),
duration: minutes(35),
price: 0.25,
rating: 4.0,
},
Event {
name: "Trade zines with a punk on BART".to_owned(),
duration: minutes(30),
price: 3.5,
rating: 4.7,
},
Event {
name: "Get a tattoo of the Git logo".to_owned(),
duration: hours(1),
price: 200.0,
rating: 4.6,
},
]
}
}