New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TabWidget #271
TabWidget #271
Conversation
Hi, it looks awesome so far. I can review it deeply tomorrow. If it is ok for you I can fix the styling after the PR is merged 😉. You are very welcome to create PRs for the other widgets. A sub module extra would be fine, similar o the behaviors sub module. Thank very much |
Sure, i'm still learning how to use the css theming system properly. Also, looking to how you style the widget can guide me to what is the looking design that Orbtk want to achieve, so in future i could also help with design.
Ok, i will improve the documentation of the widgets and i will send tomorrow. |
In the meanwhile we switched from css to a custom RON based solution. You find a short example on the Readme. I have an initial design created by two of my colleagues. Unfortunately it is not complete and created with a propitious tool. When I develop a new widget I use the other widgets as orientation for colors and fonts and use the material design guidelines for sizes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A last few words:
- Could you add a tabwidget example please? And add the example to the examples README.
- Add the TabWidget to the Changelog file.
- Could you please use
cargo fmt
add the end?
A common appearance of the code is a important point for me. Therefore some of the comments.
The tabheader must be extended that it possible to scroll through the tab header items. There are different concepts how it could be done e.g. with left, right and overflow button or just a simple scroll bar. But it isn't needed now. It could be done in a later update (new PR).
Thank you. It's a really great work and it is also an important widget for OrbTk!
const BODY_CONTAINER: &str = "body_container"; | ||
|
||
#[derive(Default,AsAny)] | ||
pub struct TabHeaderState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add documentation please.
@@ -0,0 +1,382 @@ | |||
use crate::prelude::*; | |||
|
|||
const HEADER_CONTAINER: &str = "header_container"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this please.
// --- KEYS --
const HEADER_CONTAINER: &str = "header_container";
const BODY_CONTAINER: &str = "body_container";
// --- KEYS --
crates/widgets/src/tab_widget.rs
Outdated
|
||
|
||
widget!( | ||
/// The `TabHeader` widget is used internally to managege tabs headers. Not meant for other uses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: managege => managed
crates/widgets/src/tab_widget.rs
Outdated
} | ||
} | ||
|
||
pub enum Action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it need to be public add documentation please otherwise remove pub.
} | ||
|
||
#[derive(Default, AsAny)] | ||
pub struct TabWidgetState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it need to be public add documentation please otherwise remove pub.
crates/widgets/src/tab_widget.rs
Outdated
|
||
fn select_by_index_internal(&mut self,ctx: &mut Context,mut index: usize) | ||
{ | ||
if self.tabs.len() == 0 {return;}//No tabs could be selected if there are no one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you change it to
//No tabs could be selected if there are no one
if self.tabs.len() == 0 {return;}
please?
crates/widgets/src/tab_widget.rs
Outdated
} | ||
|
||
widget!( | ||
/// The `TabWidget` widget can store and control multiple tabs with arbitrary content. Only the selected tab will show it's content. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a documentation example please?
/// The `TabWidget` widget can store and control multiple tabs with arbitrary content. Only the selected tab will show it's content.
///
/// This example creates a TabWidget:
/// ```rust
/// TabWidget::new()
/// .tab("Tab header 1",TextBlock::new().text("Tab content 1").build(ctx))
/// .tab("Tab header 2",TextBlock::new().text("Tab content 2").build(ctx))
/// .tab("Tab header 3",TextBlock::new().text("Tab content 3").build(ctx))
/// .build(ctx)
/// ```
crates/widgets/src/tab_widget.rs
Outdated
) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add
// --- Helpers --
please.
} | ||
|
||
impl Template for TabWidget { | ||
fn template(self, id: Entity, ctx: &mut BuildContext) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now it is not possible that a child expands over the whole height of the body container. I would suggest to change the template as following:
self.name("TabWidget").close_button(true).child(
Grid::new()
.rows(Rows::new().add(32).add("*"))
.child(
Stack::new()
.id(HEADER_CONTAINER)
.orientation("horizontal")
.spacing(id)
.build(ctx),
)
.child(
Grid::new()
.attach(Grid::row(1))
.id(BODY_CONTAINER)
.build(ctx),
)
.build(ctx),
)
}
crates/widgets/src/tab_widget.rs
Outdated
.border_radius(4.0) | ||
.border_width(0.0) | ||
.border_brush("transparent") | ||
.padding((16.0, 0.0, 16.0, 0.0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you do me a favor and remove all .0s? e.g. .padding((16, 0, 16, 0))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was sure that they all require floats, sorry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not any more. No problem
All the problems that you have reported should have been fixed. I also took the opportunity to enable the possibility to toggle the visibility of the close button. I have prepared a fast example that allow to check this feature:
In this example, if you scroll the mouse wheel, the close button visibility will be inverted. If there are something else to be fixed (or maybe something that i have missed), please tell me, so i will quickly fix it. Edit:
Just a moment and i will fix them. |
Added a TabWidget example. Executed `cargo fmt`
Done. |
Yes it’s normal if other files where not formatted with cargo fmt. Thank you I will review your changes tonight 🙂. |
I also got this problem but i have fixed it before pushing the commit. Let me check... |
TabHeader::new()
.visibility(if self.close_button_visibility {
Visibility::Visible
} else {
Visibility::Collapsed
}) This could it be? |
Yes it is. If I remove this code part the tab headers are displayed. |
Yes, that is the problem, i set the wrong property, it should be:
So this set the visibility on button only, not the whole header. |
… of the wrong entity
Done, sorry for the inconvenience. |
Hi no problem. Thank you for your work. |
Merged ;-). WIll make it a little bit more styleable and adjust the style a little bit ok? |
Of course, it really needs it ^^ |
@uniformbuffer styling is done. |
I'm seeing it right now. Wow, that does not even look like the same widget. It's a very good styling job 😄 |
Thank you :-). Good styling very good base ;-) |
Hi,
for an application that i'm making i needed a tab widget to manage the user interface, so i have realized it. I think that now it is in a good shape from a functionality point of view, visually it is ugly but at least work correctly. Maybe with some css magic could be better.
Since i saw that there is a tab widget request on the project page, i thought: "why not share?".
Following an example code that i have used during testing:
Currently the TabWidget does not share values about tabs because setting them from the outside could lead into inconsistencies because i cannot get some change callbacks that hint the widget to change state. So for now the widget state is managed internally by the TabWidgetState structure.
The widget will not draw everything during the update call, but only what it is changed, so this make it very lightweight.
There are 2 values shared by TabWidget:
I'm writing some other widgets that are less fundamental and more specialized. If you want i can also share those (maybe putting in a separated folder inside widget folder called "extra" or something similar?)
Some of those widget already completed:
Hope it could be useful,
Have a good day