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

Convenience methods to add multiple children to layouts, etc #26

Open
NoraCodes opened this issue Jun 14, 2018 · 8 comments
Open

Convenience methods to add multiple children to layouts, etc #26

NoraCodes opened this issue Jun 14, 2018 · 8 comments
Labels
c-enhancement New feature or request p-low Low Priority x-good first issue Good for newcomers
Milestone

Comments

@NoraCodes
Copy link
Collaborator

Several controls, especially Group and {Vertical, Horizontal}Box, could be much more ergonomic to use if they provided an interface looking something like the following:

fn add_all(&mut self, ctx: &UI, children: Vec<Control>)

These are of course not precisely the correct types, but the general shape of the interface is correct. Adding many children is a pain, and this would make it easier.

Bonus points if it takes impl Iterator<Item=Control> or similar.

@NoraCodes NoraCodes added c-enhancement New feature or request x-good first issue Good for newcomers p-low Low Priority labels Jun 14, 2018
@delbonis
Copy link

delbonis commented Jun 28, 2018

Is there a reason we have to pass the ctx: &UI everywhere by hand? Is there a way that it could be hidden and inferred when needed?

@NoraCodes
Copy link
Collaborator Author

NoraCodes commented Jun 28, 2018 via email

@delbonis
Copy link

Perhaps change the design so that when you, for example, call Label::new(), it doesn't actually make any calls to libui, instead giving you an unbound label object. Then take this and go build your whole UI with these unbound object. Then later, you go and instantiate the view by giving it to the actual UI object that would traverse the tree and create everything in one shot. You'd keep track of the bindings to the ui* objects internally, away from the user. And I don't know enough about the internals of libui to know how you'd implement mutating the UI tree, later on though.

Of course this would require a pretty major refactoring so that's annoying. 🤷‍♂️

@NoraCodes
Copy link
Collaborator Author

NoraCodes commented Jun 28, 2018 via email

@NoraCodes
Copy link
Collaborator Author

This is like the solution we were discussion to #54 and will likely be solved in the same way.

@NoraCodes NoraCodes added this to the 0.5 Release milestone Feb 26, 2019
@tobia
Copy link

tobia commented Apr 2, 2019

The UI context reference allows iui to ensure, at compile time, that you your code will not call libui functions prior to initialization, which would be unsound.

That is the only reason? Could this not be done by checking some global flag before calling any C methods and panic if it is not set?

Or rather, if a panic-like behaviour is what you mean by "unsound", then let just that happen. I cannot imagine somebody not calling UI::init() and then complaining about a panic or other crash.

@Inc0n
Copy link

Inc0n commented Mar 26, 2020

I agree with what this comment said about hiding away ctx:&UI, ImGui, i think, does it in a similar way.

A global context is created on ImGui::init().
Whenever a functions that requires the context, it can get the context with ImGui::get_current_context()

@NoraCodes NoraCodes reopened this Mar 26, 2020
@bdamitz
Copy link

bdamitz commented Sep 13, 2020

Just spitballing, perhaps we could create a trait like

trait Bind: UnboundedControl {
    fn bind(&mut self, _ctx: &UI);
}

where control-specific bindings are run for rust data structs impl UnboundedControl. Theoretically this should mean unsafe C code is only called during bind()? This would allow a model like

let mut win = Window::new("Test App", 200, 200, WindowType::NoMenubar);
win.bind(&ui);

Then unbounded controls could be added with recursive calls to bind() by UI and its children with syntax like

ui.add(win);    // would call `bind()` on `win`
// or
ui.add_all([
    Window::new("Test App", 200, 200, WindowType::NoMenubar)
        .set_child(
            Button::new("Button")
                .on_clicked(move |btn| {
                    btn.set_text("Clicked!")
                 }) // Unbounded controls follow a builder pattern -> &mut Self?
        ),
    Window::new(...),
    ...
]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-enhancement New feature or request p-low Low Priority x-good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants