Immediate-Mode-UI / Nuklear

A single-header ANSI C immediate mode cross-platform GUI library
https://immediate-mode-ui.github.io/Nuklear/doc/index.html
Other
9.17k stars 553 forks source link

Is there some kind of multicombobox? #571

Closed 8dcc closed 1 year ago

8dcc commented 1 year ago

I looked in the wiki and in the header itself and I couldn't find anything. Maybe it has another name, but is there some kind of multicombobox implemented? Meaning a combobox where you can select multiple options.

This project is big, and I don't really know how user-friendly/practical it is meant to be, but I thought you could just implement something like this. Pseudocode:

/* Nuklear: */

struct nk_multicombo_opt {
    const char* str;
    bool selected;
};

void nk_multicombo(nk_context ctx, struct nk_multicombo_opt* opts /* ... */) {
    /* TODO: Display options, etc. */

    if (clicked(i))
        nk_multicombo_opt->selected ^= 1;

    /* ... */
}
/* User: */

struct nk_multicombo_opt opts[] = {
    { "Option 1", false },
    { "Option 2", false },
    { "Option 3", true },
    { "Option 4", true },
};

nk_multicombo(ctx, opts /* ... */);

if (opts[1].selected && opts[3].selected)
    /* ... */

PD: Some part of me really wishes that there is already a multicombobox with a different name and I wrote all this for nothing.

eleriaqueen commented 1 year ago

Nuklear seems to have many tools for combo boxes, but what do you mean by selecting multiple options ? As far as I know combo boxes usually have only one selected option.

/* =============================================================================
 *
 *                                  COMBOBOX
 *
 * ============================================================================= */
NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
NK_API int nk_combo_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size);
NK_API int nk_combo_string(struct nk_context*, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size);
NK_API int nk_combo_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void *userdata, int selected, int count, int item_height, struct nk_vec2 size);
NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
NK_API void nk_combobox_string(struct nk_context*, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size);
NK_API void nk_combobox_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int *selected, int count, int item_height, struct nk_vec2 size);
NK_API void nk_combobox_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void*, int *selected, int count, int item_height, struct nk_vec2 size);
/* =============================================================================
 *
 *                                  ABSTRACT COMBOBOX
 *
 * ============================================================================= */
NK_API nk_bool nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_symbol(struct nk_context*,  enum nk_symbol_type,  struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_image(struct nk_context*, struct nk_image img,  struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
NK_API nk_bool nk_combo_begin_image_text(struct nk_context*,  const char *selected, int, struct nk_image, struct nk_vec2 size);
NK_API nk_bool nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
NK_API nk_bool nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
NK_API nk_bool nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
NK_API nk_bool nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
NK_API nk_bool nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
NK_API nk_bool nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
NK_API void nk_combo_close(struct nk_context*);
NK_API void nk_combo_end(struct nk_context*);
8dcc commented 1 year ago

Well, I think my example was pretty clear. Normally with a combobox you select an option, and it changes the value of the selected pointer to the index of the item you just selected:

char* opts[] = {
    "opt0",
    "opt1",
    "opt2",  /* If you click this, the value of the pointer is set to 2 */
    "opt3",
};

However, what I want is being able to select more than one option, so in the above example I might want to select "opt2" and "opt3". Storing multiple selections with just a int* is not possible, and that's why I posted that pseudo-code in my first comment.

Maybe this image can help you understand what I mean, although I have no idea where this is from:

image

In that example I would want to select more than one option. Obviously, ignore the typing part and the visual checkbox.

quadroli commented 1 year ago

Hello @8dcc I am unaware whether Nuklear has such a widget.. But, how about using multiple nk_checkbox_label() widgets nested in a nk_tree_push()? From my pov it'll kinda have the same effect..

8dcc commented 1 year ago

Hello @quadroli, although that's the functionality I was looking for, it's not exactly how I expect it to look.

I found an example in a (pretty funny) YouTube video from a very loud and aggressive person: Link.

SwooshyCueb commented 1 year ago

IMO for this kind of thing you're going to want the checkboxes like in @8dcc's comment, as they very clearly convey that the user can make multiple selections. Without them, it is not made clear to the user that multiple selections are possible.

8dcc commented 1 year ago

IMO for this kind of thing you're going to want the checkboxes like in @8dcc's comment, as they very clearly convey that the user can make multiple selections. Without them, it is not made clear to the user that multiple selections are possible.

Well, showing which selections are enabled to the user should be pretty easy, just change the background color of the selected options just like it's done currently with a combobox.

Although I do understand what you mean, initially there would be no obvious visual difference between a normal and a multiple option combobox. In my case that does not matter since the context would make that obvious, but I get that the changes need to be more general.

r4klatif commented 1 year ago

just wrap ordinary calls to nk_checkbox_label() between nk_combo_begin_label() and nk_combo_end() e.g.

if(nk_combo_begin_label(ctx, "Dropdown", nk_vec2(200, 200)))
{
    nk_layout_row_dynamic(ctx, 0, 1);
    nk_checkbox_label(ctx, "Option A", &a);
    nk_checkbox_label(ctx, "Option B", &b);
    nk_combo_end(ctx);
}

beware, you can't stack multiple comboboxes inside of eachother because of the way 'nuklear windows' work.

8dcc commented 1 year ago

I guess this will have to do.

8dcc commented 9 months ago

Instead of nk_checkbox_label, I think nk_selectable_label is what I was looking for.