Blame src-nuklear/nuklear_toggle.c

Ivan Mahonin b53a5c
#include "nuklear.h"
Ivan Mahonin b53a5c
#include "nuklear_internal.h"
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
/* ===============================================================
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 *                              TOGGLE
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * ===============================================================*/
Ivan Mahonin b53a5c
NK_LIB nk_bool
Ivan Mahonin b53a5c
nk_toggle_behavior(const struct nk_input *in, struct nk_rect select,
Ivan Mahonin b53a5c
    nk_flags *state, nk_bool active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    nk_widget_state_reset(state);
Ivan Mahonin b53a5c
    if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
Ivan Mahonin b53a5c
        *state = NK_WIDGET_STATE_ACTIVE;
Ivan Mahonin b53a5c
        active = !active;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select))
Ivan Mahonin b53a5c
        *state |= NK_WIDGET_STATE_ENTERED;
Ivan Mahonin b53a5c
    else if (nk_input_is_mouse_prev_hovering_rect(in, select))
Ivan Mahonin b53a5c
        *state |= NK_WIDGET_STATE_LEFT;
Ivan Mahonin b53a5c
    return active;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_LIB void
Ivan Mahonin b53a5c
nk_draw_checkbox(struct nk_command_buffer *out,
Ivan Mahonin b53a5c
    nk_flags state, const struct nk_style_toggle *style, nk_bool active,
Ivan Mahonin b53a5c
    const struct nk_rect *label, const struct nk_rect *selector,
Ivan Mahonin b53a5c
    const struct nk_rect *cursors, const char *string, int len,
Ivan Mahonin b53a5c
    const struct nk_user_font *font)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    const struct nk_style_item *background;
Ivan Mahonin b53a5c
    const struct nk_style_item *cursor;
Ivan Mahonin b53a5c
    struct nk_text text;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* select correct colors/images */
Ivan Mahonin b53a5c
    if (state & NK_WIDGET_STATE_HOVER) {
Ivan Mahonin b53a5c
        background = &style->hover;
Ivan Mahonin b53a5c
        cursor = &style->cursor_hover;
Ivan Mahonin b53a5c
        text.text = style->text_hover;
Ivan Mahonin b53a5c
    } else if (state & NK_WIDGET_STATE_ACTIVED) {
Ivan Mahonin b53a5c
        background = &style->hover;
Ivan Mahonin b53a5c
        cursor = &style->cursor_hover;
Ivan Mahonin b53a5c
        text.text = style->text_active;
Ivan Mahonin b53a5c
    } else {
Ivan Mahonin b53a5c
        background = &style->normal;
Ivan Mahonin b53a5c
        cursor = &style->cursor_normal;
Ivan Mahonin b53a5c
        text.text = style->text_normal;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw background and cursor */
Ivan Mahonin b53a5c
    if (background->type == NK_STYLE_ITEM_COLOR) {
Ivan Mahonin b53a5c
        nk_fill_rect(out, *selector, 0, style->border_color);
Ivan Mahonin b53a5c
        nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color);
Ivan Mahonin b53a5c
    } else nk_draw_image(out, *selector, &background->data.image, nk_white);
Ivan Mahonin b53a5c
    if (active) {
Ivan Mahonin b53a5c
        if (cursor->type == NK_STYLE_ITEM_IMAGE)
Ivan Mahonin b53a5c
            nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
Ivan Mahonin b53a5c
        else nk_fill_rect(out, *cursors, 0, cursor->data.color);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    text.padding.x = 0;
Ivan Mahonin b53a5c
    text.padding.y = 0;
Ivan Mahonin b53a5c
    text.background = style->text_background;
Ivan Mahonin b53a5c
    nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_LIB void
Ivan Mahonin b53a5c
nk_draw_option(struct nk_command_buffer *out,
Ivan Mahonin b53a5c
    nk_flags state, const struct nk_style_toggle *style, nk_bool active,
Ivan Mahonin b53a5c
    const struct nk_rect *label, const struct nk_rect *selector,
Ivan Mahonin b53a5c
    const struct nk_rect *cursors, const char *string, int len,
Ivan Mahonin b53a5c
    const struct nk_user_font *font)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    const struct nk_style_item *background;
Ivan Mahonin b53a5c
    const struct nk_style_item *cursor;
Ivan Mahonin b53a5c
    struct nk_text text;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* select correct colors/images */
Ivan Mahonin b53a5c
    if (state & NK_WIDGET_STATE_HOVER) {
Ivan Mahonin b53a5c
        background = &style->hover;
Ivan Mahonin b53a5c
        cursor = &style->cursor_hover;
Ivan Mahonin b53a5c
        text.text = style->text_hover;
Ivan Mahonin b53a5c
    } else if (state & NK_WIDGET_STATE_ACTIVED) {
Ivan Mahonin b53a5c
        background = &style->hover;
Ivan Mahonin b53a5c
        cursor = &style->cursor_hover;
Ivan Mahonin b53a5c
        text.text = style->text_active;
Ivan Mahonin b53a5c
    } else {
Ivan Mahonin b53a5c
        background = &style->normal;
Ivan Mahonin b53a5c
        cursor = &style->cursor_normal;
Ivan Mahonin b53a5c
        text.text = style->text_normal;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw background and cursor */
Ivan Mahonin b53a5c
    if (background->type == NK_STYLE_ITEM_COLOR) {
Ivan Mahonin b53a5c
        nk_fill_circle(out, *selector, style->border_color);
Ivan Mahonin b53a5c
        nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color);
Ivan Mahonin b53a5c
    } else nk_draw_image(out, *selector, &background->data.image, nk_white);
Ivan Mahonin b53a5c
    if (active) {
Ivan Mahonin b53a5c
        if (cursor->type == NK_STYLE_ITEM_IMAGE)
Ivan Mahonin b53a5c
            nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
Ivan Mahonin b53a5c
        else nk_fill_circle(out, *cursors, cursor->data.color);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    text.padding.x = 0;
Ivan Mahonin b53a5c
    text.padding.y = 0;
Ivan Mahonin b53a5c
    text.background = style->text_background;
Ivan Mahonin b53a5c
    nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_LIB nk_bool
Ivan Mahonin b53a5c
nk_do_toggle(nk_flags *state,
Ivan Mahonin b53a5c
    struct nk_command_buffer *out, struct nk_rect r,
Ivan Mahonin b53a5c
    nk_bool *active, const char *str, int len, enum nk_toggle_type type,
Ivan Mahonin b53a5c
    const struct nk_style_toggle *style, const struct nk_input *in,
Ivan Mahonin b53a5c
    const struct nk_user_font *font)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int was_active;
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    struct nk_rect select;
Ivan Mahonin b53a5c
    struct nk_rect cursor;
Ivan Mahonin b53a5c
    struct nk_rect label;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(style);
Ivan Mahonin b53a5c
    NK_ASSERT(out);
Ivan Mahonin b53a5c
    NK_ASSERT(font);
Ivan Mahonin b53a5c
    if (!out || !style || !font || !active)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    r.w = NK_MAX(r.w, font->height + 2 * style->padding.x);
Ivan Mahonin b53a5c
    r.h = NK_MAX(r.h, font->height + 2 * style->padding.y);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* add additional touch padding for touch screen devices */
Ivan Mahonin b53a5c
    bounds.x = r.x - style->touch_padding.x;
Ivan Mahonin b53a5c
    bounds.y = r.y - style->touch_padding.y;
Ivan Mahonin b53a5c
    bounds.w = r.w + 2 * style->touch_padding.x;
Ivan Mahonin b53a5c
    bounds.h = r.h + 2 * style->touch_padding.y;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* calculate the selector space */
Ivan Mahonin b53a5c
    select.w = font->height;
Ivan Mahonin b53a5c
    select.h = select.w;
Ivan Mahonin b53a5c
    select.y = r.y + r.h/2.0f - select.h/2.0f;
Ivan Mahonin b53a5c
    select.x = r.x;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* calculate the bounds of the cursor inside the selector */
Ivan Mahonin b53a5c
    cursor.x = select.x + style->padding.x + style->border;
Ivan Mahonin b53a5c
    cursor.y = select.y + style->padding.y + style->border;
Ivan Mahonin b53a5c
    cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
Ivan Mahonin b53a5c
    cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* label behind the selector */
Ivan Mahonin b53a5c
    label.x = select.x + select.w + style->spacing;
Ivan Mahonin b53a5c
    label.y = select.y;
Ivan Mahonin b53a5c
    label.w = NK_MAX(r.x + r.w, label.x) - label.x;
Ivan Mahonin b53a5c
    label.h = select.w;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* update selector */
Ivan Mahonin b53a5c
    was_active = *active;
Ivan Mahonin b53a5c
    *active = nk_toggle_behavior(in, bounds, state, *active);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw selector */
Ivan Mahonin b53a5c
    if (style->draw_begin)
Ivan Mahonin b53a5c
        style->draw_begin(out, style->userdata);
Ivan Mahonin b53a5c
    if (type == NK_TOGGLE_CHECK) {
Ivan Mahonin b53a5c
        nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
Ivan Mahonin b53a5c
    } else {
Ivan Mahonin b53a5c
        nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    if (style->draw_end)
Ivan Mahonin b53a5c
        style->draw_end(out, style->userdata);
Ivan Mahonin b53a5c
    return (was_active != *active);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
/*----------------------------------------------------------------
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 *                          CHECKBOX
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * --------------------------------------------------------------*/
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_check_text(struct nk_context *ctx, const char *text, int len, nk_bool active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_window *win;
Ivan Mahonin b53a5c
    struct nk_panel *layout;
Ivan Mahonin b53a5c
    const struct nk_input *in;
Ivan Mahonin b53a5c
    const struct nk_style *style;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    enum nk_widget_layout_states state;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current->layout);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current || !ctx->current->layout)
Ivan Mahonin b53a5c
        return active;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    win = ctx->current;
Ivan Mahonin b53a5c
    style = &ctx->style;
Ivan Mahonin b53a5c
    layout = win->layout;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    state = nk_widget(&bounds, ctx);
Ivan Mahonin b53a5c
    if (!state) return active;
Ivan Mahonin b53a5c
    in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
Ivan Mahonin b53a5c
    nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
Ivan Mahonin b53a5c
        text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font);
Ivan Mahonin b53a5c
    return active;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API unsigned int
Ivan Mahonin b53a5c
nk_check_flags_text(struct nk_context *ctx, const char *text, int len,
Ivan Mahonin b53a5c
    unsigned int flags, unsigned int value)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int old_active;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(text);
Ivan Mahonin b53a5c
    if (!ctx || !text) return flags;
Ivan Mahonin b53a5c
    old_active = (int)((flags & value) & value);
Ivan Mahonin b53a5c
    if (nk_check_text(ctx, text, len, old_active))
Ivan Mahonin b53a5c
        flags |= value;
Ivan Mahonin b53a5c
    else flags &= ~value;
Ivan Mahonin b53a5c
    return flags;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_checkbox_text(struct nk_context *ctx, const char *text, int len, nk_bool *active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int old_val;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(text);
Ivan Mahonin b53a5c
    NK_ASSERT(active);
Ivan Mahonin b53a5c
    if (!ctx || !text || !active) return 0;
Ivan Mahonin b53a5c
    old_val = *active;
Ivan Mahonin b53a5c
    *active = nk_check_text(ctx, text, len, *active);
Ivan Mahonin b53a5c
    return old_val != *active;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len,
Ivan Mahonin b53a5c
    unsigned int *flags, unsigned int value)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    nk_bool active;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(text);
Ivan Mahonin b53a5c
    NK_ASSERT(flags);
Ivan Mahonin b53a5c
    if (!ctx || !text || !flags) return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    active = (int)((*flags & value) & value);
Ivan Mahonin b53a5c
    if (nk_checkbox_text(ctx, text, len, &active)) {
Ivan Mahonin b53a5c
        if (active) *flags |= value;
Ivan Mahonin b53a5c
        else *flags &= ~value;
Ivan Mahonin b53a5c
        return 1;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    return 0;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool nk_check_label(struct nk_context *ctx, const char *label, nk_bool active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_check_text(ctx, label, nk_strlen(label), active);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label,
Ivan Mahonin b53a5c
    unsigned int flags, unsigned int value)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool nk_checkbox_label(struct nk_context *ctx, const char *label, nk_bool *active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_checkbox_text(ctx, label, nk_strlen(label), active);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool nk_checkbox_flags_label(struct nk_context *ctx, const char *label,
Ivan Mahonin b53a5c
    unsigned int *flags, unsigned int value)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
/*----------------------------------------------------------------
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 *                          OPTION
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * --------------------------------------------------------------*/
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_option_text(struct nk_context *ctx, const char *text, int len, nk_bool is_active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_window *win;
Ivan Mahonin b53a5c
    struct nk_panel *layout;
Ivan Mahonin b53a5c
    const struct nk_input *in;
Ivan Mahonin b53a5c
    const struct nk_style *style;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    enum nk_widget_layout_states state;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current->layout);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current || !ctx->current->layout)
Ivan Mahonin b53a5c
        return is_active;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    win = ctx->current;
Ivan Mahonin b53a5c
    style = &ctx->style;
Ivan Mahonin b53a5c
    layout = win->layout;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    state = nk_widget(&bounds, ctx);
Ivan Mahonin b53a5c
    if (!state) return (int)state;
Ivan Mahonin b53a5c
    in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
Ivan Mahonin b53a5c
    nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
Ivan Mahonin b53a5c
        text, len, NK_TOGGLE_OPTION, &style->option, in, style->font);
Ivan Mahonin b53a5c
    return is_active;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_radio_text(struct nk_context *ctx, const char *text, int len, nk_bool *active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int old_value;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(text);
Ivan Mahonin b53a5c
    NK_ASSERT(active);
Ivan Mahonin b53a5c
    if (!ctx || !text || !active) return 0;
Ivan Mahonin b53a5c
    old_value = *active;
Ivan Mahonin b53a5c
    *active = nk_option_text(ctx, text, len, old_value);
Ivan Mahonin b53a5c
    return old_value != *active;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_option_label(struct nk_context *ctx, const char *label, nk_bool active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_option_text(ctx, label, nk_strlen(label), active);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_radio_label(struct nk_context *ctx, const char *label, nk_bool *active)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return nk_radio_text(ctx, label, nk_strlen(label), active);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c