| Index: libs/ui/export/libui.h | 
| — | — | @@ -31,6 +31,7 @@ | 
| 32 | 32 | #include "../chooser_action_handler_wheel.h" | 
| 33 | 33 | #include "../chooser_renderer_list.h" | 
| 34 | 34 | #include "../chooser_renderer_iconflow.h" | 
|  | 35 | +#include "../settingchooser.h" | 
| 35 | 36 |  | 
| 36 | 37 |  | 
| 37 | 38 | /* emCORE library identifier */ | 
| — | — | @@ -37,12 +38,12 @@ | 
| 38 | 39 | #define LIBUI_IDENTIFIER 0x49554365 | 
| 39 | 40 |  | 
| 40 | 41 | /* increase this every time the api struct changes */ | 
| 41 |  | -#define LIBUI_API_VERSION 2
 | 
|  | 42 | +#define LIBUI_API_VERSION 3 | 
| 42 | 43 |  | 
| 43 | 44 | /* update this to latest version if a change to the api struct breaks | 
| 44 | 45 | backwards compatibility (and please take the opportunity to sort in any | 
| 45 | 46 | new function which are "waiting" at the end of the function table) */ | 
| 46 |  | -#define LIBUI_MIN_API_VERSION 2
 | 
|  | 47 | +#define LIBUI_MIN_API_VERSION 3 | 
| 47 | 48 |  | 
| 48 | 49 | /* NOTE: To support backwards compatibility, only add new functions at | 
| 49 | 50 | the end of the structure.  Every time you add a new function, | 
| — | — | @@ -61,6 +62,10 @@ | 
| 62 | 63 | typeof(chooser_action_handler_wheel)* chooser_action_handler_wheel; | 
| 63 | 64 | typeof(chooser_renderer_list)* chooser_renderer_list; | 
| 64 | 65 | typeof(chooser_renderer_iconflow)* chooser_renderer_iconflow; | 
|  | 66 | +    typeof(chooser_renderer_list_render_attached_text)* chooser_renderer_list_render_attached_text; | 
|  | 67 | +    typeof(chooser_renderer_list_show_arrow_right)* chooser_renderer_list_show_arrow_right; | 
|  | 68 | +    typeof(chooser_renderer_list_show_arrow_left)* chooser_renderer_list_show_arrow_left; | 
|  | 69 | +    typeof(settingchooser_run)* settingchooser_run; | 
| 65 | 70 | }; | 
| 66 | 71 |  | 
| 67 | 72 | #endif | 
| Index: libs/ui/SOURCES | 
| — | — | @@ -4,3 +4,4 @@ | 
| 5 | 5 | chooser_action_handler_wheel.c | 
| 6 | 6 | chooser_renderer_list.c | 
| 7 | 7 | chooser_renderer_iconflow.c | 
|  | 8 | +settingchooser.c | 
| Index: libs/ui/chooser.c | 
| — | — | @@ -31,24 +31,24 @@ | 
| 32 | 32 | struct chooser_data* data = (struct chooser_data*)user; | 
| 33 | 33 | switch (data->info->actionhandler->handleevent(data, event, which, value)) | 
| 34 | 34 | { | 
| 35 |  | -    case CHOOSER_RESULT_REDRAW:
 | 
| 36 |  | -        mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 37 |  | -        data->redrawneeded = true;
 | 
| 38 |  | -        wakeup_signal(&data->eventwakeup);
 | 
| 39 |  | -        mutex_unlock(&data->statemutex);
 | 
| 40 |  | -        break;
 | 
| 41 |  | -    case CHOOSER_RESULT_CANCEL:
 | 
| 42 |  | -        mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 43 |  | -        data->canceled = true;
 | 
| 44 |  | -        wakeup_signal(&data->eventwakeup);
 | 
| 45 |  | -        mutex_unlock(&data->statemutex);
 | 
| 46 |  | -        break;
 | 
| 47 |  | -    case CHOOSER_RESULT_FINISHED:
 | 
| 48 |  | -        mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 49 |  | -        data->finished = true;
 | 
| 50 |  | -        wakeup_signal(&data->eventwakeup);
 | 
| 51 |  | -        mutex_unlock(&data->statemutex);
 | 
| 52 |  | -        break;
 | 
|  | 35 | +        case CHOOSER_RESULT_REDRAW: | 
|  | 36 | +            mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 37 | +            data->redrawneeded = true; | 
|  | 38 | +            wakeup_signal(&data->eventwakeup); | 
|  | 39 | +            mutex_unlock(&data->statemutex); | 
|  | 40 | +            break; | 
|  | 41 | +        case CHOOSER_RESULT_CANCEL: | 
|  | 42 | +            mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 43 | +            data->canceled = true; | 
|  | 44 | +            wakeup_signal(&data->eventwakeup); | 
|  | 45 | +            mutex_unlock(&data->statemutex); | 
|  | 46 | +            break; | 
|  | 47 | +        case CHOOSER_RESULT_FINISHED: | 
|  | 48 | +            mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 49 | +            data->finished = true; | 
|  | 50 | +            wakeup_signal(&data->eventwakeup); | 
|  | 51 | +            mutex_unlock(&data->statemutex); | 
|  | 52 | +            break; | 
| 53 | 53 | } | 
| 54 | 54 | } | 
| 55 | 55 |  | 
| — | — | @@ -99,13 +99,13 @@ | 
| 100 | 100 | if (info->actionhandler->handletick) | 
| 101 | 101 | switch (info->actionhandler->handletick(&data)) | 
| 102 | 102 | { | 
| 103 |  | -                case CHOOSER_RESULT_REDRAW:
 | 
| 104 |  | -                    redrawneeded = true;
 | 
| 105 |  | -                    break;
 | 
| 106 |  | -                case CHOOSER_RESULT_CANCEL:
 | 
| 107 |  | -                    goto cancel;
 | 
| 108 |  | -                case CHOOSER_RESULT_FINISHED:
 | 
| 109 |  | -                    goto finished;
 | 
|  | 103 | +                    case CHOOSER_RESULT_REDRAW: | 
|  | 104 | +                        redrawneeded = true; | 
|  | 105 | +                        break; | 
|  | 106 | +                    case CHOOSER_RESULT_CANCEL: | 
|  | 107 | +                        goto cancel; | 
|  | 108 | +                    case CHOOSER_RESULT_FINISHED: | 
|  | 109 | +                        goto finished; | 
| 110 | 110 | } | 
| 111 | 111 | lasttick = USEC_TIMER; | 
| 112 | 112 | } | 
| Index: libs/ui/chooser.h | 
| — | — | @@ -83,7 +83,7 @@ | 
| 84 | 84 | long tickinterval; | 
| 85 | 85 | int itemcount; | 
| 86 | 86 | int defaultitem; | 
| 87 |  | -    const struct chooser_item items[];
 | 
|  | 87 | +    struct chooser_item items[]; | 
| 88 | 88 | }; | 
| 89 | 89 |  | 
| 90 | 90 | struct chooser_data | 
| Index: libs/ui/libui.h | 
| — | — | @@ -35,6 +35,7 @@ | 
| 36 | 36 | .addr = a,             \ | 
| 37 | 37 | .stride = b            \ | 
| 38 | 38 | } | 
|  | 39 | +#define LIBUI_BUFFER_NULL LIBUI_BUFFER(NULL, 0) | 
| 39 | 40 |  | 
| 40 | 41 | struct libui_point | 
| 41 | 42 | { | 
| — | — | @@ -46,6 +47,7 @@ | 
| 47 | 48 | .x = a,               \ | 
| 48 | 49 | .y = b                \ | 
| 49 | 50 | } | 
|  | 51 | +#define LIBUI_POINT_NULL LIBUI_POINT(0, 0) | 
| 50 | 52 |  | 
| 51 | 53 | struct libui_box | 
| 52 | 54 | { | 
| — | — | @@ -57,6 +59,7 @@ | 
| 58 | 60 | .pos = a,           \ | 
| 59 | 61 | .size = b           \ | 
| 60 | 62 | } | 
|  | 63 | +#define LIBUI_BOX_NULL LIBUI_BOX(LIBUI_POINT_NULL, LIBUI_POINT_NULL) | 
| 61 | 64 |  | 
| 62 | 65 | struct libui_location | 
| 63 | 66 | { | 
| — | — | @@ -68,6 +71,7 @@ | 
| 69 | 72 | .buf = a,                \ | 
| 70 | 73 | .pos = b                 \ | 
| 71 | 74 | } | 
|  | 75 | +#define LIBUI_LOCATION_NULL LIBUI_LOCATION(LIBUI_BUFFER_NULL, LIBUI_POINT_NULL) | 
| 72 | 76 |  | 
| 73 | 77 | struct libui_surface | 
| 74 | 78 | { | 
| — | — | @@ -79,5 +83,6 @@ | 
| 80 | 84 | .loc = a,               \ | 
| 81 | 85 | .size = b               \ | 
| 82 | 86 | } | 
|  | 87 | +#define LIBUI_SURFACE_NULL LIBUI_SURFACE(LIBUI_LOCATION_NULL, LIBUI_POINT_NULL) | 
| 83 | 88 |  | 
| 84 | 89 | #endif | 
| Index: libs/ui/chooser_action_handler_wheel.c | 
| — | — | @@ -55,35 +55,36 @@ | 
| 56 | 56 | int spi = params->stepsperitem; | 
| 57 | 57 | switch (event) | 
| 58 | 58 | { | 
| 59 |  | -    case BUTTON_PRESS:
 | 
| 60 |  | -        if (which < params->buttoncount)
 | 
| 61 |  | -            switch (params->buttonmap[which])
 | 
| 62 |  | -            {
 | 
| 63 |  | -            case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV:
 | 
| 64 |  | -                mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 65 |  | -                data->position = MIN(data->info->itemcount * spi,
 | 
| 66 |  | -                                     MAX(spi, data->position & ~(spi - 1))) - spi / 2;
 | 
| 67 |  | -                data->selected = &data->info->items[data->position / spi];
 | 
| 68 |  | -                mutex_unlock(&data->statemutex);
 | 
| 69 |  | -                return CHOOSER_RESULT_REDRAW;
 | 
| 70 |  | -            case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT:
 | 
| 71 |  | -                mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 72 |  | -                data->position = MIN(data->info->itemcount * spi,
 | 
| 73 |  | -                                     MAX(spi, (data->position & ~(spi - 1)) + 2 * spi)) - spi / 2;
 | 
| 74 |  | -                data->selected = &data->info->items[data->position / spi];
 | 
| 75 |  | -                mutex_unlock(&data->statemutex);
 | 
| 76 |  | -                return CHOOSER_RESULT_REDRAW;
 | 
| 77 |  | -            case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT:
 | 
| 78 |  | -                return CHOOSER_RESULT_FINISHED;
 | 
| 79 |  | -            case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_CANCEL:
 | 
| 80 |  | -                return CHOOSER_RESULT_CANCEL;
 | 
| 81 |  | -            }
 | 
| 82 |  | -    case WHEEL_MOVED_ACCEL:
 | 
| 83 |  | -        mutex_lock(&data->statemutex, TIMEOUT_BLOCK);
 | 
| 84 |  | -        data->position = MIN(data->info->itemcount * spi - 1, MAX(0, data->position + value));
 | 
| 85 |  | -        data->selected = &data->info->items[data->position / spi];
 | 
| 86 |  | -        mutex_unlock(&data->statemutex);
 | 
| 87 |  | -        return CHOOSER_RESULT_REDRAW;
 | 
|  | 59 | +        case BUTTON_PRESS: | 
|  | 60 | +            if (which < params->buttoncount) | 
|  | 61 | +                switch (params->buttonmap[which]) | 
|  | 62 | +                { | 
|  | 63 | +                    case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV: | 
|  | 64 | +                        mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 65 | +                        data->position = MIN(data->info->itemcount * spi, | 
|  | 66 | +                                             MAX(spi, data->position & ~(spi - 1))) - spi / 2; | 
|  | 67 | +                        data->selected = &data->info->items[data->position / spi]; | 
|  | 68 | +                        mutex_unlock(&data->statemutex); | 
|  | 69 | +                        return CHOOSER_RESULT_REDRAW; | 
|  | 70 | +                    case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT: | 
|  | 71 | +                        mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 72 | +                        data->position = MIN(data->info->itemcount * spi, | 
|  | 73 | +                                             MAX(spi, (data->position & ~(spi - 1)) + 2 * spi)) | 
|  | 74 | +                                                    - spi / 2; | 
|  | 75 | +                        data->selected = &data->info->items[data->position / spi]; | 
|  | 76 | +                        mutex_unlock(&data->statemutex); | 
|  | 77 | +                        return CHOOSER_RESULT_REDRAW; | 
|  | 78 | +                    case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT: | 
|  | 79 | +                        return CHOOSER_RESULT_FINISHED; | 
|  | 80 | +                    case CHOOSER_ACTION_HANDLER_WHEEL_ACTION_CANCEL: | 
|  | 81 | +                        return CHOOSER_RESULT_CANCEL; | 
|  | 82 | +                } | 
|  | 83 | +        case WHEEL_MOVED_ACCEL: | 
|  | 84 | +            mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 85 | +            data->position = MIN(data->info->itemcount * spi - 1, MAX(0, data->position + value)); | 
|  | 86 | +            data->selected = &data->info->items[data->position / spi]; | 
|  | 87 | +            mutex_unlock(&data->statemutex); | 
|  | 88 | +            return CHOOSER_RESULT_REDRAW; | 
| 88 | 89 | } | 
| 89 | 90 | return CHOOSER_RESULT_OK; | 
| 90 | 91 | } | 
| Index: libs/ui/chooser_renderer_list.c | 
| — | — | @@ -187,6 +187,7 @@ | 
| 188 | 188 | if (iparams->text && iparams->text_color) | 
| 189 | 189 | rendertext(buf, x + iparams->text_pos.x, y + iparams->text_pos.y, | 
| 190 | 190 | stride, text_color, 0, iparams->text); | 
|  | 191 | +        if (iparams->render) iparams->render(data, item, item == selected, x, y); | 
| 191 | 192 | y += iparams->size.y; | 
| 192 | 193 | item++; | 
| 193 | 194 | } | 
| — | — | @@ -225,7 +226,37 @@ | 
| 226 | 227 | free(data->rendererdata); | 
| 227 | 228 | } | 
| 228 | 229 |  | 
|  | 230 | +void chooser_renderer_list_render_attached_text(struct chooser_data* data, | 
|  | 231 | +                                                const struct chooser_item* item, | 
|  | 232 | +                                                bool selected, int x, int y, const char* text) | 
|  | 233 | +{ | 
|  | 234 | +    struct chooser_renderer_list_params* rparams; | 
|  | 235 | +    rparams = (struct chooser_renderer_list_params*)data->info->rendererparams; | 
|  | 236 | +    struct chooser_renderer_list_itemdata* ritem; | 
|  | 237 | +    ritem = (struct chooser_renderer_list_itemdata*)item->renderparams; | 
|  | 238 | +    void* buf = rparams->viewport.loc.buf.addr; | 
|  | 239 | +    int stride = rparams->viewport.loc.buf.stride; | 
|  | 240 | +    x += ritem->size.x - ritem->text_pos.x - strlen(text) * get_font_width(); | 
|  | 241 | +    y += ritem->text_pos.y; | 
|  | 242 | +    uint32_t color = selected ? ritem->text_color_selected : ritem->text_color; | 
|  | 243 | +    rendertext(buf, x, y, stride, color, 0, text); | 
|  | 244 | +} | 
| 229 | 245 |  | 
|  | 246 | +void chooser_renderer_list_show_arrow_right(struct chooser_data* data, | 
|  | 247 | +                                            const struct chooser_item* item, | 
|  | 248 | +                                            bool selected, int x, int y) | 
|  | 249 | +{ | 
|  | 250 | +    chooser_renderer_list_render_attached_text(data, item, selected, x, y, ">"); | 
|  | 251 | +} | 
|  | 252 | + | 
|  | 253 | +void chooser_renderer_list_show_arrow_left(struct chooser_data* data, | 
|  | 254 | +                                           const struct chooser_item* item, | 
|  | 255 | +                                           bool selected, int x, int y) | 
|  | 256 | +{ | 
|  | 257 | +    chooser_renderer_list_render_attached_text(data, item, selected, x, y, "<"); | 
|  | 258 | +} | 
|  | 259 | + | 
|  | 260 | + | 
| 230 | 261 | const struct chooser_renderer chooser_renderer_list = | 
| 231 | 262 | { | 
| 232 | 263 | .version = CHOOSER_RENDERER_VERSION, | 
| Index: libs/ui/main.c | 
| — | — | @@ -36,7 +36,11 @@ | 
| 37 | 37 | .chooser_run = chooser_run, | 
| 38 | 38 | .chooser_action_handler_wheel = &chooser_action_handler_wheel, | 
| 39 | 39 | .chooser_renderer_list = &chooser_renderer_list, | 
| 40 |  | -    .chooser_renderer_iconflow = &chooser_renderer_iconflow
 | 
|  | 40 | +    .chooser_renderer_iconflow = &chooser_renderer_iconflow, | 
|  | 41 | +    .chooser_renderer_list_render_attached_text = &chooser_renderer_list_render_attached_text, | 
|  | 42 | +    .chooser_renderer_list_show_arrow_right = &chooser_renderer_list_show_arrow_right, | 
|  | 43 | +    .chooser_renderer_list_show_arrow_left = &chooser_renderer_list_show_arrow_left, | 
|  | 44 | +    .settingchooser_run = &settingchooser_run | 
| 41 | 45 | }; | 
| 42 | 46 |  | 
| 43 | 47 | EMCORE_LIB_HEADER(LIBUI_IDENTIFIER, LIBUI_API_VERSION, LIBUI_MIN_API_VERSION, NULL, NULL, apitable) | 
| Index: libs/ui/chooser_renderer_iconflow.c | 
| — | — | @@ -158,7 +158,7 @@ | 
| 159 | 159 | const struct libui_surface* icon; | 
| 160 | 160 | if (item == selected) icon = &iparams->icon_selected; | 
| 161 | 161 | else icon = &iparams->icon; | 
| 162 |  | -        int ix, iy, io; | 
|  | 162 | +        int ix, iy, io, tx = 0, ty = 0; | 
| 163 | 163 | int dist = pos - vpos; | 
| 164 | 164 | chooser_renderer_iconflow_geticondata(x, y, w, h, spi * iiv, dist, icon, &ix, &iy, &io); | 
| 165 | 165 | if (item == selected) | 
| — | — | @@ -165,13 +165,17 @@ | 
| 166 | 166 | { | 
| 167 | 167 | io = 255; | 
| 168 | 168 | if (iparams->text && iparams->text_color) | 
| 169 |  | -                rendertext(buf, params->text_pos.x - strlen(iparams->text) * get_font_width() / 2, | 
| 170 |  | -                           params->text_pos.y, stride, iparams->text_color, 0, iparams->text); | 
|  | 169 | +            { | 
|  | 170 | +                tx = params->text_pos.x - strlen(iparams->text) * get_font_width() / 2; | 
|  | 171 | +                ty = params->text_pos.y; | 
|  | 172 | +                rendertext(buf, tx, ty, stride, iparams->text_color, 0, iparams->text); | 
|  | 173 | +           } | 
| 171 | 174 | } | 
| 172 | 175 | if (icon->loc.buf.addr && io && ix >= x && iy >= y | 
| 173 | 176 | && ix + icon->size.x <= x + w && iy + icon->size.y <= y + h) | 
| 174 | 177 | blenda(icon->size.x, icon->size.y, io, buf, ix, iy, stride, buf, ix, iy, stride, | 
| 175 | 178 | icon->loc.buf.addr, icon->loc.pos.x, icon->loc.pos.y, icon->loc.buf.stride); | 
|  | 179 | +        if (iparams->render) iparams->render(data, item, item == selected, ix, iy, io, tx, ty); | 
| 176 | 180 | if (item == selected) break; | 
| 177 | 181 | item += dir; | 
| 178 | 182 | pos += dir * spi; | 
| Index: libs/ui/chooser_renderer_list.h | 
| — | — | @@ -29,7 +29,7 @@ | 
| 30 | 30 | #include "chooser.h" | 
| 31 | 31 |  | 
| 32 | 32 |  | 
| 33 |  | -#define CHOOSER_RENDERER_LIST_PARAMS_VERSION 1
 | 
|  | 33 | +#define CHOOSER_RENDERER_LIST_PARAMS_VERSION 2 | 
| 34 | 34 |  | 
| 35 | 35 | struct chooser_renderer_list_params | 
| 36 | 36 | { | 
| — | — | @@ -59,10 +59,12 @@ | 
| 60 | 60 | int icon_opacity; | 
| 61 | 61 | struct libui_surface icon_selected; | 
| 62 | 62 | int icon_selected_opacity; | 
| 63 |  | -    char* text;
 | 
|  | 63 | +    const char* text; | 
| 64 | 64 | struct libui_point text_pos; | 
| 65 | 65 | uint32_t text_color; | 
| 66 | 66 | uint32_t text_color_selected; | 
|  | 67 | +    void (*render)(struct chooser_data* data, const struct chooser_item* item, | 
|  | 68 | +                   bool selected, int x, int y); | 
| 67 | 69 | }; | 
| 68 | 70 |  | 
| 69 | 71 | struct chooser_renderer_list_data | 
| — | — | @@ -74,5 +76,16 @@ | 
| 75 | 77 |  | 
| 76 | 78 | extern const struct chooser_renderer chooser_renderer_list; | 
| 77 | 79 |  | 
|  | 80 | +extern void chooser_renderer_list_render_attached_text(struct chooser_data* data, | 
|  | 81 | +                                                       const struct chooser_item* item, | 
|  | 82 | +                                                       bool selected, int x, int y, | 
|  | 83 | +                                                       const char* text); | 
|  | 84 | +extern void chooser_renderer_list_show_arrow_right(struct chooser_data* data, | 
|  | 85 | +                                                   const struct chooser_item* item, | 
|  | 86 | +                                                   bool selected, int x, int y); | 
|  | 87 | +extern void chooser_renderer_list_show_arrow_left(struct chooser_data* data, | 
|  | 88 | +                                                  const struct chooser_item* item, | 
|  | 89 | +                                                  bool selected, int x, int y); | 
| 78 | 90 |  | 
|  | 91 | + | 
| 79 | 92 | #endif | 
| Index: libs/ui/chooser_renderer_iconflow.h | 
| — | — | @@ -29,7 +29,7 @@ | 
| 30 | 30 | #include "chooser.h" | 
| 31 | 31 |  | 
| 32 | 32 |  | 
| 33 |  | -#define CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION 1
 | 
|  | 33 | +#define CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION 2 | 
| 34 | 34 |  | 
| 35 | 35 | struct chooser_renderer_iconflow_params | 
| 36 | 36 | { | 
| — | — | @@ -56,8 +56,10 @@ | 
| 57 | 57 | { | 
| 58 | 58 | struct libui_surface icon; | 
| 59 | 59 | struct libui_surface icon_selected; | 
| 60 |  | -    char* text;
 | 
|  | 60 | +    const char* text; | 
| 61 | 61 | uint32_t text_color; | 
|  | 62 | +    void (*render)(struct chooser_data* data, const struct chooser_item* item, | 
|  | 63 | +                   bool selected, int x, int y, int opacity, int textx, int texty); | 
| 62 | 64 | }; | 
| 63 | 65 |  | 
| 64 | 66 | struct chooser_renderer_iconflow_data |