Skip to content
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

Nested structs cause an error, internal sizing issues, but this thing is amazing! #1

Closed
1sra3l opened this issue Nov 14, 2021 · 12 comments

Comments

@1sra3l
Copy link
Contributor

1sra3l commented Nov 14, 2021

A struct within a struct causes a crash and backtrace is required to decipher nested structs do not work.
That said, nested enums, etc... work

The other issue is internal sizing, as you mentioned:
image

I think scaling the size of label is more important than the 'input', and unless something changed in FLTK you need to calculate text width by yourself. I've done it in the past based on the font size, but did not find the best solution.

All in all this is great!!! What an easy way to make a GUI for entering info!!! I can now build a GUI prefilled with values and switch between files with hardly any coding! This is so amazing!!

To sub nest a struct, the only possible way i can think is to return an Fl_Tab, with a Group for each extra struct as a tab.
If every internal struct became a tab, it could potentially create a ton of tabs, and tabs within Tabs. But AFAIK this should nest correctly and look okay.

This has me wanting to get into macros, you are really good at this stuff!! Thanks so much!

@MoAlyousef
Copy link
Collaborator

Hi
I've tried to go with some saner defaults for the sizes, and also added a way to rename properties.
Regarding nested structs, data carrying-enums, structs with unnamed fields, those would be too complex to design unfortunately, logic-wise and gui-wise. (nested structs no longer cause a compile error though)

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

😸 You are great at this!
Ok now I have a Vec<Enum> that causes errors after those have been fixed. Does this work for Vec in any form yet? Is there a way you can simply ignore all things that are not covered?

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

I suppose to support more things would require functions to show them. For instance, to actually implement nested things, opening a "sub-window" would be the way to actually do it in a program interface. But that would mean creating a container group, with all of them sub groups (like tabs) but replacing the entire visible group with a different group.
This is probably not possible to pass the switch view functions in generate?

@MoAlyousef
Copy link
Collaborator

That would be difficult. I've added an implementation for vectors, which should work for any Vec where T implements FltkForm. The problem remains (like with tuple like structs and structs with unnamed fields), there is no way to fetch back the choices since vectors don't have named fields.
I'm also considering adding a Form widget which is instantiated like any widget, but which also takes data and shows as a form.

I've added more examples of those.

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

Well you've covered every normal sue case I can think of right off the bat.
I think the previous internal formatting was more intuitive, but I see what you were going for in this iteration.
image
The vector of enum does not render the way I'd expect. It is rendering the enum::Variant in the same way the enum::{variants} is rendered itself. I hope that last part made sense to you. look at the "specials" below. It is:
specials:vec![Special::Tackle, Special::Tackle, Special::Tackle, Special::Tackle, Special::Tackle],
I suppose each variant is a MenuItem I'd expect the entire list in the Menu, but the variant MenuItem as the text displayed in the Box.
not sure waht needs to change in the impl for it. Your coding style is great, I think I can learn a lot from how you implemented this idea. Thanks for thinking of bool that is very sensible.

All in all I think for most people looking to make a really fast GUI for most reasonable use cases can basically build a struct, use serde and fltk-form. I know my edge case (in-game configuration) is small, but for anyone needing a custom struct to GUI this will be the easiest, smallest solution. It could be used as the primary UI on an embedded system, right?

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

A possible solution for:

enum MyEnum {
  This,
  That(Thing),
}

Would be to just display the Debug of Thing inside of That({:?}), and require they implement Debug. Is this possible, or is this the issue?

@MoAlyousef
Copy link
Collaborator

I started using packs instead of Flex widgets, this should fix the issues with vecs.

Setting and getting the choice value requires integral indices, which data-carrying enums can't be cast/converted into.

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

@MoAlyousef That works great! The only issue arises when I have a lot of things. Things are cut off.

The Scroll Box would fix those and any other issues with internal width/height display and would offer the best UX, I think. It does not display scrollbars if you do not need it, but if the window is too small everything fits. I used this as a base widget for most of my old C++ app windows. It fixed issues on old displays/small screens.

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

@MoAlyousef Yeah this works perfectly now, it might be better to make the example have:

//..
let mut grp = group::Scroll::default()//....
//..

I am closing the issue! Thanks!

@1sra3l 1sra3l closed this as completed Nov 14, 2021
@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

@MoAlyousef Question about the fltk::group::ScrollType.
How do I set it for the fltk::group::Scroll, in the C++ there was a function for it.... I didn't find it in Rust though

@MoAlyousef
Copy link
Collaborator

You can use set_type() or with_type().

let scroll = fltk::group::Scroll::default().with_type(fltk::group::ScrollType::BothAlways);

@1sra3l
Copy link
Contributor Author

1sra3l commented Nov 14, 2021

That might be a good default for the example code for fltk-form, so all things will work in the most expected way when copy + paste coders code it aka things in the future like copilot :

let mut grp = group::Scroll::default()
        .with_size(300, 200)
        .with_type(fltk::group::ScrollType::BothAlways)
        .center_of_parent();

I did see the with_type but was unsure if it worked for everything everywhere. Thanks!
This way if it has a bunch of items in the struct it will all be accessible through the UI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants