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

ComboBox widget (enums) #17

Open
smasher816 opened this issue Nov 9, 2019 · 8 comments
Open

ComboBox widget (enums) #17

smasher816 opened this issue Nov 9, 2019 · 8 comments
Labels
enhancement New feature or request

Comments

@smasher816
Copy link

Having a drop down box to select a variant would be awesome (I'm sadly not sure about the derive logic for this).

I could also see this being useful to select an item out of an array of values.

@smasher816
Copy link
Author

Skimming over syn it looks like you could match over Data::Enum and then iterate over .variants to get each ident (name) and fields (just as a struct would have).

If I find the time I may try to mess with this, but it will be my first time venturing into the world of proc macros so it might be slow learning the ropes.

@germangb germangb added the enhancement New feature or request label Nov 9, 2019
@germangb
Copy link
Owner

germangb commented Nov 9, 2019

What do the annotations you had in mind look like?

Keep in mind that syn doesn't know about the enum variants when you are parsing the struct fields, it only applies grammars (when parsing my_selectable in the below example).

I think this API might work (following the trait-based design of the crate)

// this derive would generate an implementation of a ComboBox trait.
#[derive(imgui_ext::ComboBox)]
enum UserEnum { ... }

#[derive(imgui_ext::Gui)]
struct MyUi {
    #[imgui(combo_box),
    my_selectable: UserEnum,
}

I'm not familiar with the ComboBox type though. I might be missing something. If it was recently introduced in imgui, then I need to fix #16 first

@smasher816
Copy link
Author

It looks like it was added in imgui 0.2.0 and not available in 0.1.0. I'll add the master branch to my project now that there is something to work off of.

I think your example of the API looks like it would work well.

@smasher816
Copy link
Author

I hacked on this a little bit just to get a proof of concept.

Combobox

Right now it will display an array, but I'm not sure how we'd store the state for the selected index. I assume it would only work for wrapper types, or for enums (where the selection is implicitly part of the value).

Patch: smasher816@9b96b53

#[derive(imgui_ext::Gui, Debug)]
pub struct Example {
    #[imgui(combobox(label = "choose one", selected = "1"))]
    vec: [ImString; 3],
}

combobox

Enum

I can parse attributes on each variant, but dealing with the types is tricky. Rending the nested contents of a variant fails because the anonymous data doesn't derive Gui, and empty variants do not parse because they have no fields.

Patch: smasher816@001f33b

#[derive(imgui_ext::Gui, Debug)]
pub enum Example {
    #[imgui(bullet(text = "OptionA"))]
    OptionA { x: usize, y: usize },
    #[imgui(bullet(text = "OptionB"))]
    OptionB { name: String },
    #[imgui(bullet(text = "OptionC"))]
    OptionC { enabled: bool },
}

enum


For now I think that is about as far as I can get on my own. Hope it helps a little.

@germangb
Copy link
Owner

germangb commented Nov 29, 2019

Hey thanks, can you open one or two PRs to discuss further?

After looking at your combobox concept I thought of this alternative API to remove the allocation and store the selected item in the struct:

#[derive(imgui_ext::Gui)]
pub struct Example {
    #[imgui(combobox(label = "choose one", items = "combo_items"))]
    selected: usize,
}

fn combo_items() -> &'static [&'static ImStr] {
    &[im_str!("Foo"),
      im_str!("Bar"),
      im_str!("Baz")]
}

What do you think?

@smasher816
Copy link
Author

Sadly rust will not let you return a reference to an array as you have in your combo_items example as the value will be dropped at the end of the function. We either have to return an owned value (Vec) or do something more creative like a callable closure than can temporarily pass in the information. I'm attempting to try the later.

@smasher816
Copy link
Author

Got it working!

#19

@germangb
Copy link
Owner

germangb commented Dec 18, 2019

(I updated a typo in the previous example)

Ah... I thought it would be easier to create a static slice of static ImStr :/

At least https://docs.rs/imgui/0.2.1/imgui/struct.ImStr.html#method.from_utf8_with_nul_unchecked would need to be made const fn, but I read it's not possible in stable Rust yet

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

No branches or pull requests

2 participants