| Index: libs/ui/settingchooser.c | 
| — | — | @@ -0,0 +1,311 @@ | 
|  | 2 | +// | 
|  | 3 | +// | 
|  | 4 | +//    Copyright 2011 TheSeven | 
|  | 5 | +// | 
|  | 6 | +// | 
|  | 7 | +//    This file is part of emCORE. | 
|  | 8 | +// | 
|  | 9 | +//    emCORE is free software: you can redistribute it and/or | 
|  | 10 | +//    modify it under the terms of the GNU General Public License as | 
|  | 11 | +//    published by the Free Software Foundation, either version 2 of the | 
|  | 12 | +//    License, or (at your option) any later version. | 
|  | 13 | +// | 
|  | 14 | +//    emCORE is distributed in the hope that it will be useful, | 
|  | 15 | +//    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | +//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 17 | +//    See the GNU General Public License for more details. | 
|  | 18 | +// | 
|  | 19 | +//    You should have received a copy of the GNU General Public License along | 
|  | 20 | +//    with emCORE.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 21 | +// | 
|  | 22 | +// | 
|  | 23 | + | 
|  | 24 | + | 
|  | 25 | +#include "emcorelib.h" | 
|  | 26 | +#include "libui.h" | 
|  | 27 | +#include "settingchooser.h" | 
|  | 28 | +#include "chooser.h" | 
|  | 29 | +#include "chooser_renderer_list.h" | 
|  | 30 | +#include "chooser_action_handler_wheel.h" | 
|  | 31 | + | 
|  | 32 | + | 
|  | 33 | +static bool settingchooser_event_filter(struct chooser_data* data, enum button_event event, | 
|  | 34 | +                                        int which, int value) | 
|  | 35 | +{ | 
|  | 36 | +    struct settingchooser_data* state = (struct settingchooser_data*)data->info->userparams; | 
|  | 37 | +    struct settingchooser_info* info = (struct settingchooser_info*)state->info; | 
|  | 38 | +    struct settingchooser_item* item = (struct settingchooser_item*)data->selected->user; | 
|  | 39 | +    struct chooser_renderer_list_itemdata* rp; | 
|  | 40 | +    rp = (struct chooser_renderer_list_itemdata*)data->selected->renderparams; | 
|  | 41 | +    bool redraw = false; | 
|  | 42 | +    bool handled = false; | 
|  | 43 | +    bool setcolors = false; | 
|  | 44 | +    switch (event) | 
|  | 45 | +    { | 
|  | 46 | +        case BUTTON_PRESS: | 
|  | 47 | +            switch (which) | 
|  | 48 | +            { | 
|  | 49 | +                case 0: | 
|  | 50 | +                    switch (item->type) | 
|  | 51 | +                    { | 
|  | 52 | +                        case SETTINGCHOOSER_TYPE_INTEGER: | 
|  | 53 | +                            handled = true; | 
|  | 54 | +                            setcolors = true; | 
|  | 55 | +                            state->editing = !state->editing; | 
|  | 56 | +                            if (state->editing) state->collect = 0; | 
|  | 57 | +                            break; | 
|  | 58 | +                    } | 
|  | 59 | +                    break; | 
|  | 60 | + | 
|  | 61 | +                case 2: | 
|  | 62 | +                    if (state->editing) | 
|  | 63 | +                    { | 
|  | 64 | +                        handled = true; | 
|  | 65 | +                        setcolors = true; | 
|  | 66 | +                        state->editing = false; | 
|  | 67 | +                    } | 
|  | 68 | +                    break; | 
|  | 69 | + | 
|  | 70 | +                default: | 
|  | 71 | +                    handled = state->editing; | 
|  | 72 | +                    break; | 
|  | 73 | +            } | 
|  | 74 | +            break; | 
|  | 75 | + | 
|  | 76 | +        case WHEEL_MOVED_ACCEL: | 
|  | 77 | +            if (state->editing) | 
|  | 78 | +            { | 
|  | 79 | +                switch (item->type) | 
|  | 80 | +                { | 
|  | 81 | +                    case SETTINGCHOOSER_TYPE_INTEGER: | 
|  | 82 | +                        handled = true; | 
|  | 83 | +                        state->collect += value; | 
|  | 84 | +                        int change = (state->collect * item->config.integer.step) / 128; | 
|  | 85 | +                        if (!change) break; | 
|  | 86 | +                        state->collect -= (change * 128) / item->config.integer.step; | 
|  | 87 | +                        int* setting = (int*)item->setting; | 
|  | 88 | +                        if (*setting + change < item->config.integer.min) | 
|  | 89 | +                            *setting = item->config.integer.min; | 
|  | 90 | +                        else if (*setting + change > item->config.integer.max) | 
|  | 91 | +                            *setting = item->config.integer.max; | 
|  | 92 | +                        else *setting += change; | 
|  | 93 | +                        if (item->validator) item->validator(item->setting); | 
|  | 94 | +                        state->changed = true; | 
|  | 95 | +                        redraw = true; | 
|  | 96 | +                        break; | 
|  | 97 | +                } | 
|  | 98 | +            } | 
|  | 99 | +            break; | 
|  | 100 | +    } | 
|  | 101 | +    if (setcolors) | 
|  | 102 | +    { | 
|  | 103 | +        if (state->editing) | 
|  | 104 | +        { | 
|  | 105 | +            rp->fill_color_selected = info->itemparams.fill_color_active; | 
|  | 106 | +            rp->text_color_selected = info->itemparams.text_color_active; | 
|  | 107 | +            rp->icon_selected_opacity = info->itemparams.icon_active_opacity; | 
|  | 108 | +        } | 
|  | 109 | +        else | 
|  | 110 | +        { | 
|  | 111 | +            rp->fill_color_selected = info->itemparams.fill_color_selected; | 
|  | 112 | +            rp->text_color_selected = info->itemparams.text_color_selected; | 
|  | 113 | +            rp->icon_selected_opacity = info->itemparams.icon_selected_opacity; | 
|  | 114 | +        } | 
|  | 115 | +        redraw = true; | 
|  | 116 | +    } | 
|  | 117 | +    if (redraw) | 
|  | 118 | +    { | 
|  | 119 | +        mutex_lock(&data->statemutex, TIMEOUT_BLOCK); | 
|  | 120 | +        data->redrawneeded = true; | 
|  | 121 | +        wakeup_signal(&data->eventwakeup); | 
|  | 122 | +        mutex_unlock(&data->statemutex); | 
|  | 123 | +    } | 
|  | 124 | +    return handled; | 
|  | 125 | +} | 
|  | 126 | + | 
|  | 127 | +static struct chooser_action_handler_wheel_params settingchooser_aparams = | 
|  | 128 | +{ | 
|  | 129 | +    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION, | 
|  | 130 | +    .stepsperitem = 128, | 
|  | 131 | +    .eventfilter = settingchooser_event_filter, | 
|  | 132 | +    .timeout_initial = TIMEOUT_BLOCK, | 
|  | 133 | +    .timeout_idle = TIMEOUT_BLOCK, | 
|  | 134 | +    .timeout_item = 0, | 
|  | 135 | +    .tick_force_redraw = true, | 
|  | 136 | +    .buttoncount = 5, | 
|  | 137 | +    .buttonmap = | 
|  | 138 | +    { | 
|  | 139 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT, | 
|  | 140 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NONE, | 
|  | 141 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_CANCEL, | 
|  | 142 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT, | 
|  | 143 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV | 
|  | 144 | +    } | 
|  | 145 | +}; | 
|  | 146 | +static struct chooser_action_handler_wheel_params settingchooser_aparams2 = | 
|  | 147 | +{ | 
|  | 148 | +    .version = CHOOSER_ACTION_HANDLER_WHEEL_PARAMS_VERSION, | 
|  | 149 | +    .stepsperitem = 128, | 
|  | 150 | +    .eventfilter = NULL, | 
|  | 151 | +    .timeout_initial = TIMEOUT_BLOCK, | 
|  | 152 | +    .timeout_idle = TIMEOUT_BLOCK, | 
|  | 153 | +    .timeout_item = 0, | 
|  | 154 | +    .tick_force_redraw = true, | 
|  | 155 | +    .buttoncount = 5, | 
|  | 156 | +    .buttonmap = | 
|  | 157 | +    { | 
|  | 158 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_SELECT, | 
|  | 159 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NONE, | 
|  | 160 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_CANCEL, | 
|  | 161 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_NEXT, | 
|  | 162 | +        CHOOSER_ACTION_HANDLER_WHEEL_ACTION_PREV | 
|  | 163 | +    } | 
|  | 164 | +}; | 
|  | 165 | + | 
|  | 166 | +static void settingchooser_render_preview(struct chooser_data* data, | 
|  | 167 | +                                          const struct chooser_item* item, | 
|  | 168 | +                                          bool selected, int x, int y) | 
|  | 169 | +{ | 
|  | 170 | +    struct settingchooser_item* itemdata = (struct settingchooser_item*)item->user; | 
|  | 171 | +    int value = *((int*)itemdata->setting); | 
|  | 172 | +    const char* str = NULL; | 
|  | 173 | +    char buf[16]; | 
|  | 174 | +    switch (itemdata->type) | 
|  | 175 | +    { | 
|  | 176 | +        case SETTINGCHOOSER_TYPE_INTEGER: | 
|  | 177 | +            if (itemdata->config.integer.tostring) | 
|  | 178 | +                itemdata->config.integer.tostring(buf, sizeof(buf), itemdata->setting, value); | 
|  | 179 | +            else snprintf(buf, sizeof(buf), "%d", value); | 
|  | 180 | +            str = buf; | 
|  | 181 | +            break; | 
|  | 182 | + | 
|  | 183 | +        case SETTINGCHOOSER_TYPE_SELECT: | 
|  | 184 | +            if (value < itemdata->config.select.options->optioncount) | 
|  | 185 | +                str = itemdata->config.select.options->options[value].preview; | 
|  | 186 | +            break; | 
|  | 187 | +    } | 
|  | 188 | +    if (str) chooser_renderer_list_render_attached_text(data, item, selected, x, y, str); | 
|  | 189 | +} | 
|  | 190 | + | 
|  | 191 | +static void settingchooser_populate_rp(const struct settingchooser_info* info, | 
|  | 192 | +                                       struct chooser_renderer_list_itemdata* rp) | 
|  | 193 | +{ | 
|  | 194 | +    rp->size = info->itemparams.size; | 
|  | 195 | +    rp->fill_box = info->itemparams.fill_box; | 
|  | 196 | +    rp->fill_color = info->itemparams.fill_color; | 
|  | 197 | +    rp->fill_color_selected = info->itemparams.fill_color_selected; | 
|  | 198 | +    rp->icon_pos = info->itemparams.icon_pos; | 
|  | 199 | +    rp->icon_opacity = info->itemparams.icon_opacity; | 
|  | 200 | +    rp->icon_selected_opacity = info->itemparams.icon_selected_opacity; | 
|  | 201 | +    rp->text_pos = info->itemparams.text_pos; | 
|  | 202 | +    rp->text_color = info->itemparams.text_color; | 
|  | 203 | +    rp->text_color_selected = info->itemparams.text_color_selected; | 
|  | 204 | +} | 
|  | 205 | + | 
|  | 206 | +bool settingchooser_run(const struct settingchooser_info* info) | 
|  | 207 | +{ | 
|  | 208 | +    int i; | 
|  | 209 | +    bool rc = false; | 
|  | 210 | +    struct chooser_renderer_list_itemdata* rp; | 
|  | 211 | +    if (info->version != SETTINGCHOOSER_INFO_VERSION) return false; | 
|  | 212 | +    int allocsize = sizeof(struct settingchooser_data) | 
|  | 213 | +                  + sizeof(struct chooser_info) | 
|  | 214 | +                  + sizeof(struct chooser_item) * (info->itemcount + 1) | 
|  | 215 | +                  + sizeof(struct chooser_renderer_list_itemdata) * (info->itemcount + 1); | 
|  | 216 | +    void* mem = malloc(allocsize); | 
|  | 217 | +    if (!mem) return false; | 
|  | 218 | +    memset(mem, 0, allocsize); | 
|  | 219 | +    void* ptr = mem; | 
|  | 220 | +    struct settingchooser_data* data = (struct settingchooser_data*)ptr; | 
|  | 221 | +    ptr += sizeof(struct settingchooser_data); | 
|  | 222 | +    struct chooser_info* chooser = (struct chooser_info*)ptr; | 
|  | 223 | +    ptr += sizeof(struct chooser_info); | 
|  | 224 | +    ptr += sizeof(struct chooser_item) * (info->itemcount + 1); | 
|  | 225 | +    for (i = 0; i < info->itemcount + 1; i++) | 
|  | 226 | +    { | 
|  | 227 | +        chooser->items[i].renderparams = (struct chooser_renderer_list_itemdata*)ptr; | 
|  | 228 | +        ptr += sizeof(struct chooser_renderer_list_itemdata); | 
|  | 229 | +    } | 
|  | 230 | +    data->info = info; | 
|  | 231 | +    chooser->version = CHOOSER_INFO_VERSION; | 
|  | 232 | +    chooser->actionhandler = &chooser_action_handler_wheel; | 
|  | 233 | +    chooser->actionhandlerparams = &settingchooser_aparams; | 
|  | 234 | +    chooser->renderer = &chooser_renderer_list; | 
|  | 235 | +    chooser->rendererparams = &info->rendererparams; | 
|  | 236 | +    chooser->userparams = data; | 
|  | 237 | +    chooser->tickinterval = info->tickinterval; | 
|  | 238 | +    chooser->itemcount = info->itemcount + 1; | 
|  | 239 | +    rp = (struct chooser_renderer_list_itemdata*)chooser->items[0].renderparams; | 
|  | 240 | +    settingchooser_populate_rp(info, rp); | 
|  | 241 | +    rp->text = info->returntext; | 
|  | 242 | +    rp->render = chooser_renderer_list_show_arrow_left; | 
|  | 243 | +    for (i = 0; i < info->itemcount; i++) | 
|  | 244 | +    { | 
|  | 245 | +        chooser->items[i + 1].user = &info->items[i]; | 
|  | 246 | +        rp = (struct chooser_renderer_list_itemdata*)chooser->items[i + 1].renderparams; | 
|  | 247 | +        settingchooser_populate_rp(info, rp); | 
|  | 248 | +        rp->text = info->items[i].text; | 
|  | 249 | +        rp->icon = info->items[i].icon; | 
|  | 250 | +        rp->icon_selected = info->items[i].icon_selected; | 
|  | 251 | +        rp->render = settingchooser_render_preview; | 
|  | 252 | +    } | 
|  | 253 | +    while (true) | 
|  | 254 | +    { | 
|  | 255 | +        const struct chooser_item* result = chooser_run(chooser); | 
|  | 256 | +        if (!result) break; | 
|  | 257 | +        struct settingchooser_item* item = (struct settingchooser_item*)result->user; | 
|  | 258 | +        if (!item) break; | 
|  | 259 | +        chooser->defaultitem = result - chooser->items; | 
|  | 260 | +        const struct settingchooser_select_options* options = item->config.select.options; | 
|  | 261 | +        int allocsize2 = sizeof(struct chooser_info) | 
|  | 262 | +                       + sizeof(struct chooser_item) * (options->optioncount + 1) | 
|  | 263 | +                       + sizeof(struct chooser_renderer_list_itemdata) | 
|  | 264 | +                       * (options->optioncount + 1); | 
|  | 265 | +        void* mem2 = malloc(allocsize2); | 
|  | 266 | +        if (!mem2) continue; | 
|  | 267 | +        memset(mem2, 0, allocsize2); | 
|  | 268 | +        void* ptr = mem2; | 
|  | 269 | +        struct chooser_info* chooser2 = (struct chooser_info*)ptr; | 
|  | 270 | +        ptr += sizeof(struct chooser_info); | 
|  | 271 | +        ptr += sizeof(struct chooser_item) * (options->optioncount + 1); | 
|  | 272 | +        for (i = 0; i < options->optioncount + 1; i++) | 
|  | 273 | +        { | 
|  | 274 | +            chooser2->items[i].renderparams = (struct chooser_renderer_list_itemdata*)ptr; | 
|  | 275 | +            ptr += sizeof(struct chooser_renderer_list_itemdata); | 
|  | 276 | +        } | 
|  | 277 | +        chooser2->version = CHOOSER_INFO_VERSION; | 
|  | 278 | +        chooser2->actionhandler = &chooser_action_handler_wheel; | 
|  | 279 | +        chooser2->actionhandlerparams = &settingchooser_aparams; | 
|  | 280 | +        chooser2->renderer = &chooser_renderer_list; | 
|  | 281 | +        chooser2->rendererparams = &info->rendererparams; | 
|  | 282 | +        chooser2->userparams = data; | 
|  | 283 | +        chooser2->tickinterval = info->tickinterval; | 
|  | 284 | +        chooser2->itemcount = options->optioncount + 1; | 
|  | 285 | +        chooser2->defaultitem = *((int*)item->setting) + 1; | 
|  | 286 | +        rp = (struct chooser_renderer_list_itemdata*)chooser2->items[0].renderparams; | 
|  | 287 | +        settingchooser_populate_rp(info, rp); | 
|  | 288 | +        rp->text = "Cancel"; | 
|  | 289 | +        rp->render = chooser_renderer_list_show_arrow_left; | 
|  | 290 | +        for (i = 0; i < options->optioncount; i++) | 
|  | 291 | +        { | 
|  | 292 | +            chooser2->items[i + 1].user = &options->options[i]; | 
|  | 293 | +            rp = (struct chooser_renderer_list_itemdata*)chooser2->items[i + 1].renderparams; | 
|  | 294 | +            settingchooser_populate_rp(info, rp); | 
|  | 295 | +            rp->text = options->options[i].text; | 
|  | 296 | +            rp->icon = options->options[i].icon; | 
|  | 297 | +            rp->icon_selected = options->options[i].icon_selected; | 
|  | 298 | +        } | 
|  | 299 | +        result = chooser_run(chooser2); | 
|  | 300 | +        int value = result - chooser2->items; | 
|  | 301 | +        if (result && value && *((int*)item->setting) != value - 1) | 
|  | 302 | +        { | 
|  | 303 | +            data->changed = true; | 
|  | 304 | +            *((int*)item->setting) = value - 1; | 
|  | 305 | +            if (item->validator) item->validator(item->setting); | 
|  | 306 | +        } | 
|  | 307 | +        free(mem2); | 
|  | 308 | +    } | 
|  | 309 | +    rc = data->changed; | 
|  | 310 | +    free(mem); | 
|  | 311 | +    return rc; | 
|  | 312 | +} | 
| Index: libs/ui/settingchooser.h | 
| — | — | @@ -0,0 +1,133 @@ | 
|  | 2 | +// | 
|  | 3 | +// | 
|  | 4 | +//    Copyright 2011 TheSeven | 
|  | 5 | +// | 
|  | 6 | +// | 
|  | 7 | +//    This file is part of emCORE. | 
|  | 8 | +// | 
|  | 9 | +//    emCORE is free software: you can redistribute it and/or | 
|  | 10 | +//    modify it under the terms of the GNU General Public License as | 
|  | 11 | +//    published by the Free Software Foundation, either version 2 of the | 
|  | 12 | +//    License, or (at your option) any later version. | 
|  | 13 | +// | 
|  | 14 | +//    emCORE is distributed in the hope that it will be useful, | 
|  | 15 | +//    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | +//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 
|  | 17 | +//    See the GNU General Public License for more details. | 
|  | 18 | +// | 
|  | 19 | +//    You should have received a copy of the GNU General Public License along | 
|  | 20 | +//    with emCORE.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 21 | +// | 
|  | 22 | +// | 
|  | 23 | + | 
|  | 24 | + | 
|  | 25 | +#ifndef __SETTINGCHOOSER_H__ | 
|  | 26 | +#define __SETTINGCHOOSER_H__ | 
|  | 27 | + | 
|  | 28 | +#include "emcorelib.h" | 
|  | 29 | +#include "libui.h" | 
|  | 30 | +#include "chooser_renderer_list.h" | 
|  | 31 | + | 
|  | 32 | + | 
|  | 33 | +struct settingchooser_item_config_integer | 
|  | 34 | +{ | 
|  | 35 | +    int min; | 
|  | 36 | +    int max; | 
|  | 37 | +    int step; | 
|  | 38 | +    int (*tostring)(char* buf, int buflen, void* setting, int value); | 
|  | 39 | +}; | 
|  | 40 | + | 
|  | 41 | +struct settingchooser_select_option | 
|  | 42 | +{ | 
|  | 43 | +    const char* preview; | 
|  | 44 | +    const char* text; | 
|  | 45 | +    struct libui_surface icon; | 
|  | 46 | +    struct libui_surface icon_selected; | 
|  | 47 | +}; | 
|  | 48 | +#define SETTINGCHOOSER_SELECT_OPTION(a, b, c, d) \ | 
|  | 49 | +{                      \ | 
|  | 50 | +    .preview = a,      \ | 
|  | 51 | +    .text = b,         \ | 
|  | 52 | +    .icon = c,         \ | 
|  | 53 | +    .icon_selected = d \ | 
|  | 54 | +} | 
|  | 55 | +#define SETTINGCHOOSER_SELECT_OPTION_NULL \ | 
|  | 56 | +    SETTINGCHOOSER_SELECT_OPTION(NULL, NULL, LIBUI_SURFACE_NULL, LIBUI_SURFACE_NULL) | 
|  | 57 | + | 
|  | 58 | +struct settingchooser_select_options | 
|  | 59 | +{ | 
|  | 60 | +    int optioncount; | 
|  | 61 | +    struct settingchooser_select_option options[]; | 
|  | 62 | +}; | 
|  | 63 | + | 
|  | 64 | +struct settingchooser_item_config_select | 
|  | 65 | +{ | 
|  | 66 | +    const struct settingchooser_select_options* options; | 
|  | 67 | +}; | 
|  | 68 | + | 
|  | 69 | +union settingchooser_item_config | 
|  | 70 | +{ | 
|  | 71 | +    struct settingchooser_item_config_integer integer; | 
|  | 72 | +    struct settingchooser_item_config_select select; | 
|  | 73 | +}; | 
|  | 74 | + | 
|  | 75 | +enum settingchooser_type | 
|  | 76 | +{ | 
|  | 77 | +    SETTINGCHOOSER_TYPE_NULL = 0, | 
|  | 78 | +    SETTINGCHOOSER_TYPE_INTEGER, | 
|  | 79 | +    SETTINGCHOOSER_TYPE_SELECT | 
|  | 80 | +}; | 
|  | 81 | + | 
|  | 82 | +struct settingchooser_item | 
|  | 83 | +{ | 
|  | 84 | +    const char* text; | 
|  | 85 | +    struct libui_surface icon; | 
|  | 86 | +    struct libui_surface icon_selected; | 
|  | 87 | +    enum settingchooser_type type; | 
|  | 88 | +    void* setting; | 
|  | 89 | +    void (*validator)(void* setting); | 
|  | 90 | +    union settingchooser_item_config config; | 
|  | 91 | +}; | 
|  | 92 | + | 
|  | 93 | +struct settingchooser_itemparams | 
|  | 94 | +{ | 
|  | 95 | +    struct libui_point size; | 
|  | 96 | +    struct libui_box fill_box; | 
|  | 97 | +    uint32_t fill_color; | 
|  | 98 | +    uint32_t fill_color_selected; | 
|  | 99 | +    uint32_t fill_color_active; | 
|  | 100 | +    struct libui_point icon_pos; | 
|  | 101 | +    int icon_opacity; | 
|  | 102 | +    int icon_selected_opacity; | 
|  | 103 | +    int icon_active_opacity; | 
|  | 104 | +    struct libui_point text_pos; | 
|  | 105 | +    uint32_t text_color; | 
|  | 106 | +    uint32_t text_color_selected; | 
|  | 107 | +    uint32_t text_color_active; | 
|  | 108 | +}; | 
|  | 109 | + | 
|  | 110 | +#define SETTINGCHOOSER_INFO_VERSION 1 | 
|  | 111 | +struct settingchooser_info | 
|  | 112 | +{ | 
|  | 113 | +    int version; | 
|  | 114 | +    struct chooser_renderer_list_params rendererparams; | 
|  | 115 | +    struct settingchooser_itemparams itemparams; | 
|  | 116 | +    const char* returntext; | 
|  | 117 | +    long tickinterval; | 
|  | 118 | +    int itemcount; | 
|  | 119 | +    const struct settingchooser_item items[]; | 
|  | 120 | +}; | 
|  | 121 | + | 
|  | 122 | +struct settingchooser_data | 
|  | 123 | +{ | 
|  | 124 | +    const struct settingchooser_info* info; | 
|  | 125 | +    bool changed; | 
|  | 126 | +    bool editing; | 
|  | 127 | +    int collect; | 
|  | 128 | +}; | 
|  | 129 | + | 
|  | 130 | + | 
|  | 131 | +bool settingchooser_run(const struct settingchooser_info* info); | 
|  | 132 | + | 
|  | 133 | + | 
|  | 134 | +#endif |