Merge pull request #2253 from iced-rs/improve-ergonomics
Improve some widget ergonomics
This commit is contained in:
commit
84cc9f130b
24 changed files with 204 additions and 150 deletions
|
|
@ -71,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Add a capacity limit to the `GlyphCache` in `iced_tiny_skia`. [#2210](https://github.com/iced-rs/iced/pull/2210)
|
- Add a capacity limit to the `GlyphCache` in `iced_tiny_skia`. [#2210](https://github.com/iced-rs/iced/pull/2210)
|
||||||
- Use pointer equality to speed up `PartialEq` implementation of `image::Bytes`. [#2220](https://github.com/iced-rs/iced/pull/2220)
|
- Use pointer equality to speed up `PartialEq` implementation of `image::Bytes`. [#2220](https://github.com/iced-rs/iced/pull/2220)
|
||||||
- Update `bitflags`, `glam`, `kurbo`, `ouroboros`, `qrcode`, and `sysinfo` dependencies. [#2227](https://github.com/iced-rs/iced/pull/2227)
|
- Update `bitflags`, `glam`, `kurbo`, `ouroboros`, `qrcode`, and `sysinfo` dependencies. [#2227](https://github.com/iced-rs/iced/pull/2227)
|
||||||
|
- Improve some widget ergonomics. [#2253](https://github.com/iced-rs/iced/pull/2253)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Clipping of `TextInput` selection. [#2199](https://github.com/iced-rs/iced/pull/2199)
|
- Clipping of `TextInput` selection. [#2199](https://github.com/iced-rs/iced/pull/2199)
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ impl Sandbox for Example {
|
||||||
text(&self.text),
|
text(&self.text),
|
||||||
"What is your language?",
|
"What is your language?",
|
||||||
combo_box,
|
combo_box,
|
||||||
vertical_space(150),
|
vertical_space().height(150),
|
||||||
]
|
]
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.align_items(Alignment::Center)
|
.align_items(Alignment::Center)
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ impl Application for Editor {
|
||||||
"Save file",
|
"Save file",
|
||||||
self.is_dirty.then_some(Message::SaveFile)
|
self.is_dirty.then_some(Message::SaveFile)
|
||||||
),
|
),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
pick_list(
|
pick_list(
|
||||||
highlighter::Theme::ALL,
|
highlighter::Theme::ALL,
|
||||||
Some(self.theme),
|
Some(self.theme),
|
||||||
|
|
@ -179,7 +179,7 @@ impl Application for Editor {
|
||||||
} else {
|
} else {
|
||||||
String::from("New file")
|
String::from("New file")
|
||||||
}),
|
}),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
text({
|
text({
|
||||||
let (line, column) = self.content.cursor_position();
|
let (line, column) = self.content.cursor_position();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ impl Sandbox for Gradient {
|
||||||
transparent,
|
transparent,
|
||||||
} = *self;
|
} = *self;
|
||||||
|
|
||||||
let gradient_box = container(horizontal_space(Length::Fill))
|
let gradient_box = container(horizontal_space())
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.style(move |_: &_| {
|
.style(move |_: &_| {
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ impl Application for Layout {
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
let header = row![
|
let header = row![
|
||||||
text(self.example.title).size(20).font(Font::MONOSPACE),
|
text(self.example.title).size(20).font(Font::MONOSPACE),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
checkbox("Explain", self.explain)
|
checkbox("Explain", self.explain)
|
||||||
.on_toggle(Message::ExplainToggled),
|
.on_toggle(Message::ExplainToggled),
|
||||||
pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected),
|
pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected),
|
||||||
|
|
@ -117,7 +117,7 @@ impl Application for Layout {
|
||||||
.on_press(Message::Previous)
|
.on_press(Message::Previous)
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
Some(horizontal_space(Length::Fill).into()),
|
Some(horizontal_space().into()),
|
||||||
(!self.example.is_last()).then_some(
|
(!self.example.is_last()).then_some(
|
||||||
button("Next →")
|
button("Next →")
|
||||||
.padding([5, 10])
|
.padding([5, 10])
|
||||||
|
|
@ -251,16 +251,16 @@ fn row_<'a>() -> Element<'a, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn space<'a>() -> Element<'a, Message> {
|
fn space<'a>() -> Element<'a, Message> {
|
||||||
row!["Left!", horizontal_space(Length::Fill), "Right!"].into()
|
row!["Left!", horizontal_space(), "Right!"].into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn application<'a>() -> Element<'a, Message> {
|
fn application<'a>() -> Element<'a, Message> {
|
||||||
let header = container(
|
let header = container(
|
||||||
row![
|
row![
|
||||||
square(40),
|
square(40),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
"Header!",
|
"Header!",
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
square(40),
|
square(40),
|
||||||
]
|
]
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ impl Sandbox for App {
|
||||||
row![
|
row![
|
||||||
text(&item.name)
|
text(&item.name)
|
||||||
.style(theme::Text::Color(item.color.into())),
|
.style(theme::Text::Color(item.color.into())),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
pick_list(Color::ALL, Some(item.color), move |color| {
|
pick_list(Color::ALL, Some(item.color), move |color| {
|
||||||
Message::ItemColorChanged(item.clone(), color)
|
Message::ItemColorChanged(item.clone(), color)
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -111,13 +111,9 @@ impl Application for App {
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
let content = container(
|
let content = container(
|
||||||
column![
|
column![
|
||||||
row![
|
row![text("Top Left"), horizontal_space(), text("Top Right")]
|
||||||
text("Top Left"),
|
.align_items(Alignment::Start)
|
||||||
horizontal_space(Length::Fill),
|
.height(Length::Fill),
|
||||||
text("Top Right")
|
|
||||||
]
|
|
||||||
.align_items(Alignment::Start)
|
|
||||||
.height(Length::Fill),
|
|
||||||
container(
|
container(
|
||||||
button(text("Show Modal")).on_press(Message::ShowModal)
|
button(text("Show Modal")).on_press(Message::ShowModal)
|
||||||
)
|
)
|
||||||
|
|
@ -127,7 +123,7 @@ impl Application for App {
|
||||||
.height(Length::Fill),
|
.height(Length::Fill),
|
||||||
row![
|
row![
|
||||||
text("Bottom Left"),
|
text("Bottom Left"),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
text("Bottom Right")
|
text("Bottom Right")
|
||||||
]
|
]
|
||||||
.align_items(Alignment::End)
|
.align_items(Alignment::End)
|
||||||
|
|
@ -157,7 +153,7 @@ impl Application for App {
|
||||||
text_input("", &self.password)
|
text_input("", &self.password)
|
||||||
.on_input(Message::Password)
|
.on_input(Message::Password)
|
||||||
.on_submit(Message::Submit)
|
.on_submit(Message::Submit)
|
||||||
.password()
|
.secure(true)
|
||||||
.padding(5),
|
.padding(5),
|
||||||
]
|
]
|
||||||
.spacing(5),
|
.spacing(5),
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ fn view_content<'a>(
|
||||||
.on_press(message)
|
.on_press(message)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut controls = column![
|
let controls = column![
|
||||||
button(
|
button(
|
||||||
"Split horizontally",
|
"Split horizontally",
|
||||||
Message::Split(pane_grid::Axis::Horizontal, pane),
|
Message::Split(pane_grid::Axis::Horizontal, pane),
|
||||||
|
|
@ -286,15 +286,16 @@ fn view_content<'a>(
|
||||||
Message::Split(pane_grid::Axis::Vertical, pane),
|
Message::Split(pane_grid::Axis::Vertical, pane),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
.spacing(5)
|
.push_maybe(if total_panes > 1 && !is_pinned {
|
||||||
.max_width(160);
|
Some(
|
||||||
|
|
||||||
if total_panes > 1 && !is_pinned {
|
|
||||||
controls = controls.push(
|
|
||||||
button("Close", Message::Close(pane))
|
button("Close", Message::Close(pane))
|
||||||
.style(theme::Button::Destructive),
|
.style(theme::Button::Destructive),
|
||||||
);
|
)
|
||||||
}
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.spacing(5)
|
||||||
|
.max_width(160);
|
||||||
|
|
||||||
let content = column![
|
let content = column![
|
||||||
text(format!("{}x{}", size.width, size.height)).size(24),
|
text(format!("{}x{}", size.width, size.height)).size(24),
|
||||||
|
|
@ -317,31 +318,31 @@ fn view_controls<'a>(
|
||||||
is_pinned: bool,
|
is_pinned: bool,
|
||||||
is_maximized: bool,
|
is_maximized: bool,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let mut row = row![].spacing(5);
|
let row = row![].spacing(5).push_maybe(if total_panes > 1 {
|
||||||
|
let (content, message) = if is_maximized {
|
||||||
|
("Restore", Message::Restore)
|
||||||
|
} else {
|
||||||
|
("Maximize", Message::Maximize(pane))
|
||||||
|
};
|
||||||
|
|
||||||
if total_panes > 1 {
|
Some(
|
||||||
let toggle = {
|
|
||||||
let (content, message) = if is_maximized {
|
|
||||||
("Restore", Message::Restore)
|
|
||||||
} else {
|
|
||||||
("Maximize", Message::Maximize(pane))
|
|
||||||
};
|
|
||||||
button(text(content).size(14))
|
button(text(content).size(14))
|
||||||
.style(theme::Button::Secondary)
|
.style(theme::Button::Secondary)
|
||||||
.padding(3)
|
.padding(3)
|
||||||
.on_press(message)
|
.on_press(message),
|
||||||
};
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
});
|
||||||
|
|
||||||
row = row.push(toggle);
|
let close = button(text("Close").size(14))
|
||||||
}
|
|
||||||
|
|
||||||
let mut close = button(text("Close").size(14))
|
|
||||||
.style(theme::Button::Destructive)
|
.style(theme::Button::Destructive)
|
||||||
.padding(3);
|
.padding(3)
|
||||||
|
.on_press_maybe(if total_panes > 1 && !is_pinned {
|
||||||
if total_panes > 1 && !is_pinned {
|
Some(Message::Close(pane))
|
||||||
close = close.on_press(Message::Close(pane));
|
} else {
|
||||||
}
|
None
|
||||||
|
});
|
||||||
|
|
||||||
row.push(close).into()
|
row.push(close).into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@ impl Sandbox for Example {
|
||||||
.placeholder("Choose a language...");
|
.placeholder("Choose a language...");
|
||||||
|
|
||||||
let content = column![
|
let content = column![
|
||||||
vertical_space(600),
|
vertical_space().height(600),
|
||||||
"Which is your favorite language?",
|
"Which is your favorite language?",
|
||||||
pick_list,
|
pick_list,
|
||||||
vertical_space(600),
|
vertical_space().height(600),
|
||||||
]
|
]
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.align_items(Alignment::Center)
|
.align_items(Alignment::Center)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use iced::widget::qr_code::{self, QRCode};
|
use iced::widget::{
|
||||||
use iced::widget::{column, container, pick_list, row, text, text_input};
|
column, container, pick_list, qr_code, row, text, text_input,
|
||||||
|
};
|
||||||
use iced::{Alignment, Element, Length, Sandbox, Settings, Theme};
|
use iced::{Alignment, Element, Length, Sandbox, Settings, Theme};
|
||||||
|
|
||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
|
|
@ -65,15 +66,16 @@ impl Sandbox for QRGenerator {
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
let mut content = column![title, input, choose_theme]
|
let content = column![title, input, choose_theme]
|
||||||
|
.push_maybe(
|
||||||
|
self.qr_code
|
||||||
|
.as_ref()
|
||||||
|
.map(|data| qr_code(data).cell_size(10)),
|
||||||
|
)
|
||||||
.width(700)
|
.width(700)
|
||||||
.spacing(20)
|
.spacing(20)
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
if let Some(qr_code) = self.qr_code.as_ref() {
|
|
||||||
content = content.push(QRCode::new(qr_code).cell_size(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
container(content)
|
container(content)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
|
|
|
||||||
|
|
@ -183,58 +183,60 @@ impl Application for Example {
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
let mut crop_controls =
|
let crop_controls =
|
||||||
column![crop_origin_controls, crop_dimension_controls]
|
column![crop_origin_controls, crop_dimension_controls]
|
||||||
|
.push_maybe(
|
||||||
|
self.crop_error
|
||||||
|
.as_ref()
|
||||||
|
.map(|error| text(format!("Crop error! \n{error}"))),
|
||||||
|
)
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
if let Some(crop_error) = &self.crop_error {
|
let controls = {
|
||||||
crop_controls =
|
let save_result =
|
||||||
crop_controls.push(text(format!("Crop error! \n{crop_error}")));
|
self.saved_png_path.as_ref().map(
|
||||||
}
|
|png_result| match png_result {
|
||||||
|
Ok(path) => format!("Png saved as: {path:?}!"),
|
||||||
|
Err(PngError(error)) => {
|
||||||
|
format!("Png could not be saved due to:\n{}", error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let mut controls = column![
|
|
||||||
column![
|
column![
|
||||||
button(centered_text("Screenshot!"))
|
column![
|
||||||
|
button(centered_text("Screenshot!"))
|
||||||
|
.padding([10, 20, 10, 20])
|
||||||
|
.width(Length::Fill)
|
||||||
|
.on_press(Message::Screenshot),
|
||||||
|
if !self.png_saving {
|
||||||
|
button(centered_text("Save as png")).on_press_maybe(
|
||||||
|
self.screenshot.is_some().then(|| Message::Png),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
button(centered_text("Saving..."))
|
||||||
|
.style(theme::Button::Secondary)
|
||||||
|
}
|
||||||
|
.style(theme::Button::Secondary)
|
||||||
.padding([10, 20, 10, 20])
|
.padding([10, 20, 10, 20])
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.on_press(Message::Screenshot),
|
]
|
||||||
if !self.png_saving {
|
.spacing(10),
|
||||||
button(centered_text("Save as png")).on_press_maybe(
|
column![
|
||||||
self.screenshot.is_some().then(|| Message::Png),
|
crop_controls,
|
||||||
)
|
button(centered_text("Crop"))
|
||||||
} else {
|
.on_press(Message::Crop)
|
||||||
button(centered_text("Saving..."))
|
.style(theme::Button::Destructive)
|
||||||
.style(theme::Button::Secondary)
|
.padding([10, 20, 10, 20])
|
||||||
}
|
.width(Length::Fill),
|
||||||
.style(theme::Button::Secondary)
|
]
|
||||||
.padding([10, 20, 10, 20])
|
.spacing(10)
|
||||||
.width(Length::Fill)
|
.align_items(Alignment::Center),
|
||||||
]
|
]
|
||||||
.spacing(10),
|
.push_maybe(save_result.map(text))
|
||||||
column![
|
.spacing(40)
|
||||||
crop_controls,
|
};
|
||||||
button(centered_text("Crop"))
|
|
||||||
.on_press(Message::Crop)
|
|
||||||
.style(theme::Button::Destructive)
|
|
||||||
.padding([10, 20, 10, 20])
|
|
||||||
.width(Length::Fill),
|
|
||||||
]
|
|
||||||
.spacing(10)
|
|
||||||
.align_items(Alignment::Center),
|
|
||||||
]
|
|
||||||
.spacing(40);
|
|
||||||
|
|
||||||
if let Some(png_result) = &self.saved_png_path {
|
|
||||||
let msg = match png_result {
|
|
||||||
Ok(path) => format!("Png saved as: {path:?}!"),
|
|
||||||
Err(PngError(error)) => {
|
|
||||||
format!("Png could not be saved due to:\n{}", error)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
controls = controls.push(text(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
let side_content = container(controls)
|
let side_content = container(controls)
|
||||||
.align_x(alignment::Horizontal::Center)
|
.align_x(alignment::Horizontal::Center)
|
||||||
|
|
|
||||||
|
|
@ -216,9 +216,9 @@ impl Application for ScrollableDemo {
|
||||||
column![
|
column![
|
||||||
scroll_to_end_button(),
|
scroll_to_end_button(),
|
||||||
text("Beginning!"),
|
text("Beginning!"),
|
||||||
vertical_space(1200),
|
vertical_space().height(1200),
|
||||||
text("Middle!"),
|
text("Middle!"),
|
||||||
vertical_space(1200),
|
vertical_space().height(1200),
|
||||||
text("End!"),
|
text("End!"),
|
||||||
scroll_to_beginning_button(),
|
scroll_to_beginning_button(),
|
||||||
]
|
]
|
||||||
|
|
@ -241,9 +241,9 @@ impl Application for ScrollableDemo {
|
||||||
row![
|
row![
|
||||||
scroll_to_end_button(),
|
scroll_to_end_button(),
|
||||||
text("Beginning!"),
|
text("Beginning!"),
|
||||||
horizontal_space(1200),
|
horizontal_space().width(1200),
|
||||||
text("Middle!"),
|
text("Middle!"),
|
||||||
horizontal_space(1200),
|
horizontal_space().width(1200),
|
||||||
text("End!"),
|
text("End!"),
|
||||||
scroll_to_beginning_button(),
|
scroll_to_beginning_button(),
|
||||||
]
|
]
|
||||||
|
|
@ -268,25 +268,25 @@ impl Application for ScrollableDemo {
|
||||||
row![
|
row![
|
||||||
column![
|
column![
|
||||||
text("Let's do some scrolling!"),
|
text("Let's do some scrolling!"),
|
||||||
vertical_space(2400)
|
vertical_space().height(2400)
|
||||||
],
|
],
|
||||||
scroll_to_end_button(),
|
scroll_to_end_button(),
|
||||||
text("Horizontal - Beginning!"),
|
text("Horizontal - Beginning!"),
|
||||||
horizontal_space(1200),
|
horizontal_space().width(1200),
|
||||||
//vertical content
|
//vertical content
|
||||||
column![
|
column![
|
||||||
text("Horizontal - Middle!"),
|
text("Horizontal - Middle!"),
|
||||||
scroll_to_end_button(),
|
scroll_to_end_button(),
|
||||||
text("Vertical - Beginning!"),
|
text("Vertical - Beginning!"),
|
||||||
vertical_space(1200),
|
vertical_space().height(1200),
|
||||||
text("Vertical - Middle!"),
|
text("Vertical - Middle!"),
|
||||||
vertical_space(1200),
|
vertical_space().height(1200),
|
||||||
text("Vertical - End!"),
|
text("Vertical - End!"),
|
||||||
scroll_to_beginning_button(),
|
scroll_to_beginning_button(),
|
||||||
vertical_space(40),
|
vertical_space().height(40),
|
||||||
]
|
]
|
||||||
.spacing(40),
|
.spacing(40),
|
||||||
horizontal_space(1200),
|
horizontal_space().width(1200),
|
||||||
text("Horizontal - End!"),
|
text("Horizontal - End!"),
|
||||||
scroll_to_beginning_button(),
|
scroll_to_beginning_button(),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ impl Sandbox for Styling {
|
||||||
|
|
||||||
let scrollable = scrollable(column![
|
let scrollable = scrollable(column![
|
||||||
"Scroll me!",
|
"Scroll me!",
|
||||||
vertical_space(800),
|
vertical_space().height(800),
|
||||||
"You did it!"
|
"You did it!"
|
||||||
])
|
])
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|
|
||||||
|
|
@ -111,11 +111,10 @@ impl Application for App {
|
||||||
column![text(title).size(14), content].spacing(5)
|
column![text(title).size(14), content].spacing(5)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut add_toast = button("Add Toast");
|
let add_toast = button("Add Toast").on_press_maybe(
|
||||||
|
(!self.editing.body.is_empty() && !self.editing.title.is_empty())
|
||||||
if !self.editing.body.is_empty() && !self.editing.title.is_empty() {
|
.then_some(Message::Add),
|
||||||
add_toast = add_toast.on_press(Message::Add);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
let content = container(
|
let content = container(
|
||||||
column![
|
column![
|
||||||
|
|
@ -274,7 +273,7 @@ mod toast {
|
||||||
container(
|
container(
|
||||||
row![
|
row![
|
||||||
text(toast.title.as_str()),
|
text(toast.title.as_str()),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
button("X")
|
button("X")
|
||||||
.on_press((on_close)(index))
|
.on_press((on_close)(index))
|
||||||
.padding(3),
|
.padding(3),
|
||||||
|
|
|
||||||
|
|
@ -56,22 +56,18 @@ impl Sandbox for Tour {
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
let Tour { steps, .. } = self;
|
let Tour { steps, .. } = self;
|
||||||
|
|
||||||
let mut controls = row![];
|
let controls = row![]
|
||||||
|
.push_maybe(steps.has_previous().then(|| {
|
||||||
if steps.has_previous() {
|
|
||||||
controls = controls.push(
|
|
||||||
button("Back")
|
button("Back")
|
||||||
.on_press(Message::BackPressed)
|
.on_press(Message::BackPressed)
|
||||||
.style(theme::Button::Secondary),
|
.style(theme::Button::Secondary)
|
||||||
|
}))
|
||||||
|
.push(horizontal_space())
|
||||||
|
.push_maybe(
|
||||||
|
steps
|
||||||
|
.can_continue()
|
||||||
|
.then(|| button("Next").on_press(Message::NextPressed)),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
controls = controls.push(horizontal_space(Length::Fill));
|
|
||||||
|
|
||||||
if steps.can_continue() {
|
|
||||||
controls =
|
|
||||||
controls.push(button("Next").on_press(Message::NextPressed));
|
|
||||||
}
|
|
||||||
|
|
||||||
let content: Element<_> = column![
|
let content: Element<_> = column![
|
||||||
steps.view(self.debug).map(Message::StepMessage),
|
steps.view(self.debug).map(Message::StepMessage),
|
||||||
|
|
@ -574,14 +570,14 @@ impl<'a> Step {
|
||||||
text("Tip: You can use the scrollbar to scroll down faster!")
|
text("Tip: You can use the scrollbar to scroll down faster!")
|
||||||
.size(16),
|
.size(16),
|
||||||
)
|
)
|
||||||
.push(vertical_space(4096))
|
.push(vertical_space().height(4096))
|
||||||
.push(
|
.push(
|
||||||
text("You are halfway there!")
|
text("You are halfway there!")
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.size(30)
|
.size(30)
|
||||||
.horizontal_alignment(alignment::Horizontal::Center),
|
.horizontal_alignment(alignment::Horizontal::Center),
|
||||||
)
|
)
|
||||||
.push(vertical_space(4096))
|
.push(vertical_space().height(4096))
|
||||||
.push(ferris(300, image::FilterMethod::Linear))
|
.push(ferris(300, image::FilterMethod::Linear))
|
||||||
.push(
|
.push(
|
||||||
text("You made it!")
|
text("You made it!")
|
||||||
|
|
@ -613,11 +609,7 @@ impl<'a> Step {
|
||||||
|
|
||||||
Self::container("Text input")
|
Self::container("Text input")
|
||||||
.push("Use a text input to ask for different kinds of information.")
|
.push("Use a text input to ask for different kinds of information.")
|
||||||
.push(if is_secure {
|
.push(text_input.secure(is_secure))
|
||||||
text_input.password()
|
|
||||||
} else {
|
|
||||||
text_input
|
|
||||||
})
|
|
||||||
.push(
|
.push(
|
||||||
checkbox("Enable password mode", is_secure)
|
checkbox("Enable password mode", is_secure)
|
||||||
.on_toggle(StepMessage::ToggleSecureInput),
|
.on_toggle(StepMessage::ToggleSecureInput),
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ impl Sandbox for VectorialText {
|
||||||
column![
|
column![
|
||||||
row![
|
row![
|
||||||
text(label),
|
text(label),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
text(format!("{:.2}", value))
|
text(format!("{:.2}", value))
|
||||||
],
|
],
|
||||||
slider(range, value, message).step(0.01)
|
slider(range, value, message).step(0.01)
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ impl Application for Example {
|
||||||
let data_row = |label, value, color| {
|
let data_row = |label, value, color| {
|
||||||
row![
|
row![
|
||||||
text(label),
|
text(label),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(),
|
||||||
text(value).font(Font::MONOSPACE).size(14).style(color),
|
text(value).font(Font::MONOSPACE).size(14).style(color),
|
||||||
]
|
]
|
||||||
.height(40)
|
.height(40)
|
||||||
|
|
@ -127,21 +127,21 @@ impl Application for Example {
|
||||||
scrollable(
|
scrollable(
|
||||||
column![
|
column![
|
||||||
text("Scroll me!"),
|
text("Scroll me!"),
|
||||||
vertical_space(400),
|
vertical_space().height(400),
|
||||||
container(text("I am the outer container!"))
|
container(text("I am the outer container!"))
|
||||||
.id(OUTER_CONTAINER.clone())
|
.id(OUTER_CONTAINER.clone())
|
||||||
.padding(40)
|
.padding(40)
|
||||||
.style(theme::Container::Box),
|
.style(theme::Container::Box),
|
||||||
vertical_space(400),
|
vertical_space().height(400),
|
||||||
scrollable(
|
scrollable(
|
||||||
column![
|
column![
|
||||||
text("Scroll me!"),
|
text("Scroll me!"),
|
||||||
vertical_space(400),
|
vertical_space().height(400),
|
||||||
container(text("I am the inner container!"))
|
container(text("I am the inner container!"))
|
||||||
.id(INNER_CONTAINER.clone())
|
.id(INNER_CONTAINER.clone())
|
||||||
.padding(40)
|
.padding(40)
|
||||||
.style(theme::Container::Box),
|
.style(theme::Container::Box),
|
||||||
vertical_space(400)
|
vertical_space().height(400),
|
||||||
]
|
]
|
||||||
.padding(20)
|
.padding(20)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,18 @@ where
|
||||||
self.children.push(child);
|
self.children.push(child);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an element to the [`Column`], if `Some`.
|
||||||
|
pub fn push_maybe(
|
||||||
|
self,
|
||||||
|
child: Option<impl Into<Element<'a, Message, Theme, Renderer>>>,
|
||||||
|
) -> Self {
|
||||||
|
if let Some(child) = child {
|
||||||
|
self.push(child)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Default for Column<'a, Message, Renderer>
|
impl<'a, Message, Renderer> Default for Column<'a, Message, Renderer>
|
||||||
|
|
|
||||||
|
|
@ -305,15 +305,15 @@ where
|
||||||
/// Creates a new horizontal [`Space`] with the given [`Length`].
|
/// Creates a new horizontal [`Space`] with the given [`Length`].
|
||||||
///
|
///
|
||||||
/// [`Space`]: crate::Space
|
/// [`Space`]: crate::Space
|
||||||
pub fn horizontal_space(width: impl Into<Length>) -> Space {
|
pub fn horizontal_space() -> Space {
|
||||||
Space::with_width(width)
|
Space::with_width(Length::Fill)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new vertical [`Space`] with the given [`Length`].
|
/// Creates a new vertical [`Space`] with the given [`Length`].
|
||||||
///
|
///
|
||||||
/// [`Space`]: crate::Space
|
/// [`Space`]: crate::Space
|
||||||
pub fn vertical_space(height: impl Into<Length>) -> Space {
|
pub fn vertical_space() -> Space {
|
||||||
Space::with_height(height)
|
Space::with_height(Length::Fill)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a horizontal [`Rule`] with the given height.
|
/// Creates a horizontal [`Rule`] with the given height.
|
||||||
|
|
@ -387,6 +387,18 @@ where
|
||||||
crate::Canvas::new(program)
|
crate::Canvas::new(program)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`QRCode`] widget from the given [`Data`].
|
||||||
|
///
|
||||||
|
/// [`QRCode`]: crate::QRCode
|
||||||
|
/// [`Data`]: crate::qr_code::Data
|
||||||
|
#[cfg(feature = "qr_code")]
|
||||||
|
pub fn qr_code<Theme>(data: &crate::qr_code::Data) -> crate::QRCode<'_, Theme>
|
||||||
|
where
|
||||||
|
Theme: crate::qr_code::StyleSheet,
|
||||||
|
{
|
||||||
|
crate::QRCode::new(data)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new [`Shader`].
|
/// Creates a new [`Shader`].
|
||||||
///
|
///
|
||||||
/// [`Shader`]: crate::Shader
|
/// [`Shader`]: crate::Shader
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,19 @@ where
|
||||||
self.children.push(child);
|
self.children.push(child);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an element to the [`Column`], if `Some`.
|
||||||
|
pub fn push_maybe(
|
||||||
|
self,
|
||||||
|
key: Key,
|
||||||
|
child: Option<impl Into<Element<'a, Message, Theme, Renderer>>>,
|
||||||
|
) -> Self {
|
||||||
|
if let Some(child) = child {
|
||||||
|
self.push(key, child)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Key, Message, Renderer> Default for Column<'a, Key, Message, Renderer>
|
impl<'a, Key, Message, Renderer> Default for Column<'a, Key, Message, Renderer>
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ where
|
||||||
content: RefCell::new(Content {
|
content: RefCell::new(Content {
|
||||||
size: Size::ZERO,
|
size: Size::ZERO,
|
||||||
layout: None,
|
layout: None,
|
||||||
element: Element::new(horizontal_space(0)),
|
element: Element::new(horizontal_space().width(0)),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,18 @@ where
|
||||||
self.children.push(child);
|
self.children.push(child);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds an element to the [`Row`], if `Some`.
|
||||||
|
pub fn push_maybe(
|
||||||
|
self,
|
||||||
|
child: Option<impl Into<Element<'a, Message, Theme, Renderer>>>,
|
||||||
|
) -> Self {
|
||||||
|
if let Some(child) = child {
|
||||||
|
self.push(child)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Default for Row<'a, Message, Renderer>
|
impl<'a, Message, Renderer> Default for Row<'a, Message, Renderer>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,18 @@ impl Space {
|
||||||
height: height.into(),
|
height: height.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the width of the [`Space`].
|
||||||
|
pub fn width(mut self, width: impl Into<Length>) -> Self {
|
||||||
|
self.width = width.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the height of the [`Space`].
|
||||||
|
pub fn height(mut self, height: impl Into<Length>) -> Self {
|
||||||
|
self.height = height.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Space
|
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Space
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the [`TextInput`] into a secure password input.
|
/// Converts the [`TextInput`] into a secure password input.
|
||||||
pub fn password(mut self) -> Self {
|
pub fn secure(mut self, is_secure: bool) -> Self {
|
||||||
self.is_secure = true;
|
self.is_secure = is_secure;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -991,9 +991,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
} else {
|
|
||||||
state.is_pasting = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.is_pasting = None;
|
||||||
}
|
}
|
||||||
Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => {
|
Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => {
|
||||||
let state = state();
|
let state = state();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue