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

List boxes #129

Closed
kayru opened this issue Feb 10, 2015 · 9 comments
Closed

List boxes #129

kayru opened this issue Feb 10, 2015 · 9 comments

Comments

@kayru
Copy link

kayru commented Feb 10, 2015

There is currently a combo box element, which allows single selection. I believe it would be useful to also add support for a list box. As a minimum implementation, it could be based on the current combo box and support single selection.

More advanced implementation could include multiple selection with user-provided storage for selected item indices.

@ocornut
Copy link
Owner

ocornut commented Feb 10, 2015

I have just drafted something (not in committable state yet)
list box

Need to handle "multiple selection" (optional) but also "single selection vs / no selection" ? (also optional) by ctrl+clicking on selected element. Instead of making a Listbox() function will all the parameters I may focus on adding the right form of Selectable widget so you can recreate the default Listbox() with a few lines and more flexibility.

@kayru
Copy link
Author

kayru commented Feb 10, 2015

Thanks for taking time to look into this! :) The draft looks pretty much like what I'm after.
Single selection vs no selection is a good point. Perhaps only the API version that allows multiple selection could support this. Single selection API would then behave essentially like a radio box, but with a scroll bar.

@ocornut
Copy link
Owner

ocornut commented Feb 10, 2015

Should be done soon. I have already committed Selectable() which is the call for a single item and the base brick to create lists.

Still tweaking on my implementations of ListBox to make sense.
Things always end up taking more work than expected :)

selectables

@kayru
Copy link
Author

kayru commented Feb 10, 2015

Aha! Looks very nice :)

@ocornut
Copy link
Owner

ocornut commented Feb 10, 2015

Here is the current state of the ListBox() function (uncommitted).
It was designed to be short enough so it actually makes sense to copy it. From this point it is trivial to create a version that does multiple-selection given your knowledge of how indices are stored. I may provide a "default" multiple selection version that output ranges of integers? But I don't want the user to feel constrained by those data types. Even indices may make less sense than pointer in some cases. Any suggestion on the right abstraction I could use?

bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_items)
{
    // FXME: This function below needs another name.
    if (!ImGui::BeginChildSelectableList(label, items_count, height_items))
        return false;

    bool value_changed = false;
    for (int i = 0; i < items_count; i++)
    {
        const bool item_selected = (i == *current_item);
        const char* item_text;
        if (!items_getter(data, i, &item_text))
            item_text = "*Unknown item*";

        ImGui::PushID(i);
        if (ImGui::Selectable(item_text, item_selected))
        {
            *current_item = i;
            value_changed = true;
        }
        ImGui::PopID();
    }

    ImGui::EndChildSelectableList();
    return value_changed;
}

Note how at this point it may even make sense to just use BeginChildSelectableList/Selectable/EndChildSelectableList and do your stuff yourself, instead of trying to fit the data via a getter.

Example code:

const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" };
static int listbox_item_current = -1, listbox_item_current2 = -1;
ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4);

ImGui::PushItemWidth(-1);
ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
ImGui::PopItemWidth();

list boxes

ocornut added a commit that referenced this issue Feb 11, 2015
Along with ListBoxHeader(), ListBoxFooter() helpers.
@ocornut
Copy link
Owner

ocornut commented Feb 11, 2015

It is committed.

API

IMGUI_API bool  ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1);
IMGUI_API bool  ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);

ListBox() looks like that. Note that it doesn't use any unexposed ImGui function.

bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items)
{
    if (!ImGui::ListBoxHeader(label, items_count, height_in_items))
        return false;

    bool value_changed = false;
    for (int i = 0; i < items_count; i++)
    {
        const bool item_selected = (i == *current_item);
        const char* item_text;
        if (!items_getter(data, i, &item_text))
            item_text = "*Unknown item*";

        ImGui::PushID(i);
        if (ImGui::Selectable(item_text, item_selected))
        {
            *current_item = i;
            value_changed = true;
        }
        ImGui::PopID();
    }

    ImGui::ListBoxFooter();
    return value_changed;
}

(I have renamed the functions to ListBoxHeader / ListBoxFooter and the earlier exist in a variant that takes size in pixels).

@ocornut
Copy link
Owner

ocornut commented Feb 11, 2015

If you have any suggestion for adding a multi-selection version in core imgui let me know.

@kayru
Copy link
Author

kayru commented Feb 11, 2015

Thanks! I shall give it a spin later today.

@ocornut
Copy link
Owner

ocornut commented Mar 5, 2015

Closing.

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

No branches or pull requests

2 participants