like the title says. It would be less tedious than creating a row/column then using push_maybe() for every item.
Edit: here an example
row![
Item1,
None,
Some(item2)
]
Edit 2: after some testing. it seems doing it like the example above is not possible.
JL710
January 24, 2025, 3:32pm
2
I understand the need of such macro but I am not sure how to implement it.
On way would be to have a macro that accepts only options like this:
row_maybe![
Some(Item1),
Some(Item2)
]
But I feel like wrapping all items in a Some is as tedious as push_maybe.
I am not shure if it is possible to have a macro that can do something like this:
row![
Item1,
None,
Some(item2)
]
How did you imagine the macro to look like?
1 Like
JL710
January 24, 2025, 3:40pm
4
I tried to find a way to do that (my second example) but could not figure out how to create a macro that can work with such inputs (mostly asked chat gpt).
yeah macros are confusing for me too. but I am very confident it’s possible. (i could be wrong tho)
JL710
January 24, 2025, 3:44pm
6
Do you know of any crate or example code that shows such macro? Maybe by looking at that code we can figure out how to do that.
no not really but let me give try i’ll get back to you if i manage to figure it out
after some testing, it’s seems it isn’t possible
If you have an iterator, you can simply use the fn column()
helper instead of column![]
. The function is effectively Column::with_children
which takes an iterator of elements, so you can use .filter_map()
to get only the values that are Some
.
Here’s an example:
use iced::widget::{column, row, text, text_input};
use iced::{Element, Size, Task};
fn main() -> iced::Result {
iced::application("iced • optional elements", App::update, App::view)
.window_size(Size::new(400.0, 400.0))
.centered()
.run_with(App::new)
}
#[derive(Debug, Clone)]
enum Message {
Input(String),
}
#[derive(Default)]
struct App {
number: u16,
}
impl App {
fn new() -> (Self, Task<Message>) {
(Self::default(), iced::widget::focus_next())
}
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Input(value) => {
self.number = value
.parse()
.ok()
.filter(|&num| num > 0 && num <= 100)
.unwrap_or(0);
Task::none()
}
}
}
fn view(&self) -> Element<Message> {
let input_value = if self.number == 0 {
String::new()
} else {
self.number.to_string()
};
column![
text_input("Enter a number from 1-100...", &input_value)
.on_input(Message::Input)
.padding(5),
text("Has these multiples up to 100:").size(16),
row(multiples(self.number).into_iter().filter_map(|opt| opt))
.spacing(10)
.wrap()
]
.padding(20)
.spacing(20)
.into()
}
}
fn multiples<'a>(divider: u16) -> impl Iterator<Item = Option<Element<'a, Message>>> {
(1..=100).map(move |n| {
if divider > 0 && n % divider == 0 {
Some(
text(format!("{:3}", n))
.size(14)
.font(iced::Font::MONOSPACE)
.into(),
)
} else {
None
}
})
}
1 Like
JL710
January 24, 2025, 7:20pm
10
I think I found a way to do something like my second code example. I will see if I find a way to implement it.
JL710
January 24, 2025, 9:42pm
11
My code did not work and although I had very good help from the rust discord it did not work.