Add interactive controls to table example
This commit is contained in:
parent
931ed20cf8
commit
2777de3c7d
2 changed files with 102 additions and 57 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
use iced::font;
|
use iced::font;
|
||||||
use iced::time::{Duration, hours, minutes};
|
use iced::time::{Duration, hours, minutes};
|
||||||
use iced::widget::{center, scrollable, table, text};
|
use iced::widget::{
|
||||||
use iced::{Element, Fill, Font};
|
center, center_x, column, container, row, scrollable, slider, table, text,
|
||||||
|
tooltip,
|
||||||
|
};
|
||||||
|
use iced::{Center, Element, Fill, Font};
|
||||||
|
|
||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
iced::application(Table::new, Table::update, Table::view).run()
|
iced::application(Table::new, Table::update, Table::view).run()
|
||||||
|
|
@ -9,20 +12,30 @@ pub fn main() -> iced::Result {
|
||||||
|
|
||||||
struct Table {
|
struct Table {
|
||||||
events: Vec<Event>,
|
events: Vec<Event>,
|
||||||
|
padding: (f32, f32),
|
||||||
|
separator: (f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Message {}
|
enum Message {
|
||||||
|
PaddingChanged(f32, f32),
|
||||||
|
SeparatorChanged(f32, f32),
|
||||||
|
}
|
||||||
|
|
||||||
impl Table {
|
impl Table {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
events: Event::list(),
|
events: Event::list(),
|
||||||
|
padding: (10.0, 5.0),
|
||||||
|
separator: (1.0, 1.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Message) {
|
fn update(&mut self, message: Message) {
|
||||||
match message {}
|
match message {
|
||||||
|
Message::PaddingChanged(x, y) => self.padding = (x, y),
|
||||||
|
Message::SeparatorChanged(x, y) => self.separator = (x, y),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<'_, Message> {
|
fn view(&self) -> Element<'_, Message> {
|
||||||
|
|
@ -34,18 +47,79 @@ impl Table {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let columns = table::definition()
|
let columns = [
|
||||||
.column(bold("Name"), |event: &Event| {
|
table::column(bold("Name"), |event: &Event| {
|
||||||
text(&event.name).width(Fill)
|
text(&event.name).width(Fill)
|
||||||
})
|
}),
|
||||||
.column(bold("Time"), |event| text!("{:?}", event.duration))
|
table::column(bold("Time"), |event: &Event| {
|
||||||
.column(bold("Price"), |event| text!("{:.2}", event.price))
|
text!("{} min", event.duration.as_secs() / 60)
|
||||||
.column(bold("Rating"), |event| text!("{:.2}", event.rating));
|
}),
|
||||||
|
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_y(5)
|
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)
|
||||||
};
|
};
|
||||||
|
|
||||||
center(scrollable(table).spacing(10)).padding(10).into()
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
column![
|
||||||
|
center(scrollable(table).spacing(10)).padding(10),
|
||||||
|
center_x(controls).padding(10).style(container::dark)
|
||||||
|
]
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,6 @@ where
|
||||||
Table::new(columns, rows)
|
Table::new(columns, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn definition<'a, T, Message, Theme, Renderer>()
|
|
||||||
-> Definition<'a, T, Message, Theme, Renderer> {
|
|
||||||
Definition {
|
|
||||||
columns: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn column<'a, T, E, Message, Theme, Renderer>(
|
pub fn column<'a, T, E, Message, Theme, Renderer>(
|
||||||
header: impl Into<Element<'a, Message, Theme, Renderer>>,
|
header: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
view: impl Fn(T) -> E + 'a,
|
view: impl Fn(T) -> E + 'a,
|
||||||
|
|
@ -133,6 +126,22 @@ where
|
||||||
self.padding_y = padding.into().0;
|
self.padding_y = padding.into().0;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn separator(self, separator: impl Into<Pixels>) -> Self {
|
||||||
|
let separator = separator.into();
|
||||||
|
|
||||||
|
self.separator_x(separator).separator_y(separator)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn separator_x(mut self, separator: impl Into<Pixels>) -> Self {
|
||||||
|
self.separator_x = separator.into().0;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn separator_y(mut self, separator: impl Into<Pixels>) -> Self {
|
||||||
|
self.separator_y = separator.into().0;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Metrics {
|
pub struct Metrics {
|
||||||
|
|
@ -452,44 +461,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Definition<
|
|
||||||
'a,
|
|
||||||
T,
|
|
||||||
Message,
|
|
||||||
Theme = crate::Theme,
|
|
||||||
Renderer = crate::Renderer,
|
|
||||||
> {
|
|
||||||
columns: Vec<Column<'a, T, Message, Theme, Renderer>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, Message, Theme, Renderer>
|
|
||||||
Definition<'a, T, Message, Theme, Renderer>
|
|
||||||
{
|
|
||||||
pub fn column<E>(
|
|
||||||
mut self,
|
|
||||||
header: impl Into<Element<'a, Message, Theme, Renderer>>,
|
|
||||||
view: impl Fn(T) -> E + 'a,
|
|
||||||
) -> Self
|
|
||||||
where
|
|
||||||
T: 'a,
|
|
||||||
E: Into<Element<'a, Message, Theme, Renderer>>,
|
|
||||||
{
|
|
||||||
self.columns.push(column(header, view));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, Message, Theme, Renderer> IntoIterator
|
|
||||||
for Definition<'a, T, Message, Theme, Renderer>
|
|
||||||
{
|
|
||||||
type Item = Column<'a, T, Message, Theme, Renderer>;
|
|
||||||
type IntoIter = ::std::vec::IntoIter<Self::Item>;
|
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.columns.into_iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Column<
|
pub struct Column<
|
||||||
'a,
|
'a,
|
||||||
T,
|
T,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue