I've experimented with a Tabs widget recently for structuring the UI using tabs. This widget was inspired by the tabs of the ionic and flutter framework.

It is also possible to define a message for handling the closing of a tab. In this case there will be a small close icon rendered on the right of each tab.

Anyone interested in such kind of widget? :)
However, there is still one problem I wasn't able to solve. This problem is about the lazy evaluation of the content of a tab. For me, the content of the tab should only be created when the tab is visible. I tried two approaches of handling this:
A closure: This works fine unless you are trying to take a reference to the application data. (The reference may not live long enough)
A trait: This could work, but hiding the specific rendering backend from the user would lead to massive code duplication.
For now it is only a TabBar wigdet and the user would need to implement the logic of the content.
A small working example currently looks like this:
use iced::{Column, Sandbox, Settings, TabBar, TabLabel, Text};
fn main() -> iced::Result {
TabsExample::run(Settings::default())
}
#[derive(Debug)]
enum Message {
TabSelected(usize),
}
struct TabsExample {
selected_tab: usize,
}
impl Sandbox for TabsExample {
type Message = Message;
fn new() -> Self {
TabsExample {
selected_tab: 0,
}
}
fn title(&self) -> String {
String::from("Tabs example")
}
fn update(&mut self, message: Self::Message) {
match message {
Message::TabSelected(index) => {
self.selected_tab = index
}
}
}
fn view(&mut self) -> iced::Element<'_, Self::Message> {
Column::new()
.push(
TabBar::new(
self.selected_tab,
vec!(
TabLabel::Text(String::from("One")),
TabLabel::Text(String::from("Two")),
TabLabel::Text(String::from("Three")),
),
Message::TabSelected,
)
)
.push(
match self.selected_tab {
0 => Text::new("One"),
1 => Text::new("Two"),
2 => Text::new("Three"),
_ => panic!()
}
)
.into()
}
}
This isn't ideal and I don't like this much.
Maybe someone else with a better knowledge about Rust has an idea of how to solve this problem. What would be the drawback of just creating the content even if the tab is not selected?
Anyone interested in such kind of widget? :)
Yes! :fire: :grinning: :fireworks: :DD
However, there is still one problem I wasn't able to solve. This problem is about the lazy evaluation of the content of a tab. For me, the content of the tab should only be created when the tab is visible. I tried two approaches of handling this:
The actual 'evaluation' of widgets (the costly/slow/expensive bits) are in two function calls to the widget:
layout()draw()If your TabBar code only call those methods on the widget for the currently-selected tab, I think you are good!
This isn't ideal and I don't like this much.
Could you elaborate? I like the idea of the TabBar being just a tab bar.
In other words, I don't think a TabBar should dictate much about the layout or position of its content. For instance, most web browsers show a (somewhat) static navbar between the tabs and their content.
Anyone interested in such kind of widget? :)
I am sure many would find this widget useful (me included!). Feel free to open-source it! Not every widget needs to make it into the main library right from the start.
This is wonderful!
I hope the close button is customisable w.r.t. the look (icon) and position (right or left of text)?
Also, would it be possible to do tab pinning, which implies that unpinned tabs can be rearranged?
(The other customization point is vertical vs. horizontal alignment of tabs)
(I dont know enough Rust to meaningfully contribute to this, I am learning it right now)
Yes! fire grinning fireworks :DD
...
If your TabBar code only call those methods on the widget for the currently-selected tab, I think you are good!
Thank you very much for your feedback! :) And I apologise for not responding until now.
Could you elaborate? I like the idea of the TabBar being just a tab bar.
Now that I've thought about it for a while, I think it's not that bad of an idea. Therefore I have decided to support both options. A TabBar Widget for a standalone TabBar and a Tabs Widget as a wrapper around the TabBar, which also handles the content (This makes the Tabs widget feel more familiar when coming from other UI frameworks).
Feel free to open-source it!
I definately will! :) And I have more good news. I have received permission from my professor to implement further widgets as part of my study project. Accordingly, more widgets will follow and will be published as well. I will talk about it in the upcomming week.
I hope the close button is customisable w.r.t. the look (icon) and position (right or left of text)?
Currently the close button will be on the right side (I've never seen the close icon on the left side before). As there are some users having problems with the SIL licence of the font/icon (#524) the user is able to set their own icon font.
Also, would it be possible to do tab pinning, which implies that unpinned tabs can be rearranged?
This is currently not implemented. I'm trying to keep it simple first.
(The other customization point is vertical vs. horizontal alignment of tabs)
I like to have vertical tabs on my browser too, but this is currently not supported as well.
Maybe I'll find some time after my project to implement some of the requested features.
(I dont know enough Rust to meaningfully contribute to this, I am learning it right now)
There is always a first time. I also learned a lot about Rust when I ventured into the TabBar. :)
Most helpful comment
Thank you very much for your feedback! :) And I apologise for not responding until now.
Now that I've thought about it for a while, I think it's not that bad of an idea. Therefore I have decided to support both options. A TabBar Widget for a standalone TabBar and a Tabs Widget as a wrapper around the TabBar, which also handles the content (This makes the Tabs widget feel more familiar when coming from other UI frameworks).
I definately will! :) And I have more good news. I have received permission from my professor to implement further widgets as part of my study project. Accordingly, more widgets will follow and will be published as well. I will talk about it in the upcomming week.
Currently the close button will be on the right side (I've never seen the close icon on the left side before). As there are some users having problems with the SIL licence of the font/icon (#524) the user is able to set their own icon font.
This is currently not implemented. I'm trying to keep it simple first.
I like to have vertical tabs on my browser too, but this is currently not supported as well.
Maybe I'll find some time after my project to implement some of the requested features.
There is always a first time. I also learned a lot about Rust when I ventured into the TabBar. :)