Blame src-nuklear/nuklear_color_picker.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
 *                          COLOR PICKER
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * ===============================================================*/
Ivan Mahonin b53a5c
NK_LIB nk_bool
Ivan Mahonin b53a5c
nk_color_picker_behavior(nk_flags *state,
Ivan Mahonin b53a5c
    const struct nk_rect *bounds, const struct nk_rect *matrix,
Ivan Mahonin b53a5c
    const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
Ivan Mahonin b53a5c
    struct nk_colorf *color, const struct nk_input *in)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    float hsva[4];
Ivan Mahonin b53a5c
    nk_bool value_changed = 0;
Ivan Mahonin b53a5c
    nk_bool hsv_changed = 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(state);
Ivan Mahonin b53a5c
    NK_ASSERT(matrix);
Ivan Mahonin b53a5c
    NK_ASSERT(hue_bar);
Ivan Mahonin b53a5c
    NK_ASSERT(color);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* color matrix */
Ivan Mahonin b53a5c
    nk_colorf_hsva_fv(hsva, *color);
Ivan Mahonin b53a5c
    if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
Ivan Mahonin b53a5c
        hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
Ivan Mahonin b53a5c
        hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
Ivan Mahonin b53a5c
        value_changed = hsv_changed = 1;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    /* hue bar */
Ivan Mahonin b53a5c
    if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
Ivan Mahonin b53a5c
        hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
Ivan Mahonin b53a5c
        value_changed = hsv_changed = 1;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    /* alpha bar */
Ivan Mahonin b53a5c
    if (alpha_bar) {
Ivan Mahonin b53a5c
        if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
Ivan Mahonin b53a5c
            hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
Ivan Mahonin b53a5c
            value_changed = 1;
Ivan Mahonin b53a5c
        }
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    nk_widget_state_reset(state);
Ivan Mahonin b53a5c
    if (hsv_changed) {
Ivan Mahonin b53a5c
        *color = nk_hsva_colorfv(hsva);
Ivan Mahonin b53a5c
        *state = NK_WIDGET_STATE_ACTIVE;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    if (value_changed) {
Ivan Mahonin b53a5c
        color->a = hsva[3];
Ivan Mahonin b53a5c
        *state = NK_WIDGET_STATE_ACTIVE;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    /* set color picker widget state */
Ivan Mahonin b53a5c
    if (nk_input_is_mouse_hovering_rect(in, *bounds))
Ivan Mahonin b53a5c
        *state = NK_WIDGET_STATE_HOVERED;
Ivan Mahonin b53a5c
    if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds))
Ivan Mahonin b53a5c
        *state |= NK_WIDGET_STATE_ENTERED;
Ivan Mahonin b53a5c
    else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
Ivan Mahonin b53a5c
        *state |= NK_WIDGET_STATE_LEFT;
Ivan Mahonin b53a5c
    return value_changed;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_LIB void
Ivan Mahonin b53a5c
nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix,
Ivan Mahonin b53a5c
    const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
Ivan Mahonin b53a5c
    struct nk_colorf col)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    NK_STORAGE const struct nk_color black = {0,0,0,255};
Ivan Mahonin b53a5c
    NK_STORAGE const struct nk_color white = {255, 255, 255, 255};
Ivan Mahonin b53a5c
    NK_STORAGE const struct nk_color black_trans = {0,0,0,0};
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    const float crosshair_size = 7.0f;
Ivan Mahonin b53a5c
    struct nk_color temp;
Ivan Mahonin b53a5c
    float hsva[4];
Ivan Mahonin b53a5c
    float line_y;
Ivan Mahonin b53a5c
    int i;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(o);
Ivan Mahonin b53a5c
    NK_ASSERT(matrix);
Ivan Mahonin b53a5c
    NK_ASSERT(hue_bar);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw hue bar */
Ivan Mahonin b53a5c
    nk_colorf_hsva_fv(hsva, col);
Ivan Mahonin b53a5c
    for (i = 0; i < 6; ++i) {
Ivan Mahonin b53a5c
        NK_GLOBAL const struct nk_color hue_colors[] = {
Ivan Mahonin b53a5c
            {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
Ivan Mahonin b53a5c
            {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
Ivan Mahonin b53a5c
        };
Ivan Mahonin b53a5c
        nk_fill_rect_multi_color(o,
Ivan Mahonin b53a5c
            nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f,
Ivan Mahonin b53a5c
                hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
Ivan Mahonin b53a5c
                hue_colors[i+1], hue_colors[i+1]);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
Ivan Mahonin b53a5c
    nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
Ivan Mahonin b53a5c
        line_y, 1, nk_rgb(255,255,255));
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw alpha bar */
Ivan Mahonin b53a5c
    if (alpha_bar) {
Ivan Mahonin b53a5c
        float alpha = NK_SATURATE(col.a);
Ivan Mahonin b53a5c
        line_y = (float)(int)(alpha_bar->y +  (1.0f - alpha) * matrix->h + 0.5f);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
        nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
Ivan Mahonin b53a5c
        nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
Ivan Mahonin b53a5c
            line_y, 1, nk_rgb(255,255,255));
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw color matrix */
Ivan Mahonin b53a5c
    temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
Ivan Mahonin b53a5c
    nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
Ivan Mahonin b53a5c
    nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* draw cross-hair */
Ivan Mahonin b53a5c
    {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2];
Ivan Mahonin b53a5c
    p.x = (float)(int)(matrix->x + S * matrix->w);
Ivan Mahonin b53a5c
    p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h);
Ivan Mahonin b53a5c
    nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
Ivan Mahonin b53a5c
    nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
Ivan Mahonin b53a5c
    nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
Ivan Mahonin b53a5c
    nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_LIB nk_bool
Ivan Mahonin b53a5c
nk_do_color_picker(nk_flags *state,
Ivan Mahonin b53a5c
    struct nk_command_buffer *out, struct nk_colorf *col,
Ivan Mahonin b53a5c
    enum nk_color_format fmt, struct nk_rect bounds,
Ivan Mahonin b53a5c
    struct nk_vec2 padding, const struct nk_input *in,
Ivan Mahonin b53a5c
    const struct nk_user_font *font)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int ret = 0;
Ivan Mahonin b53a5c
    struct nk_rect matrix;
Ivan Mahonin b53a5c
    struct nk_rect hue_bar;
Ivan Mahonin b53a5c
    struct nk_rect alpha_bar;
Ivan Mahonin b53a5c
    float bar_w;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(out);
Ivan Mahonin b53a5c
    NK_ASSERT(col);
Ivan Mahonin b53a5c
    NK_ASSERT(state);
Ivan Mahonin b53a5c
    NK_ASSERT(font);
Ivan Mahonin b53a5c
    if (!out || !col || !state || !font)
Ivan Mahonin b53a5c
        return ret;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    bar_w = font->height;
Ivan Mahonin b53a5c
    bounds.x += padding.x;
Ivan Mahonin b53a5c
    bounds.y += padding.x;
Ivan Mahonin b53a5c
    bounds.w -= 2 * padding.x;
Ivan Mahonin b53a5c
    bounds.h -= 2 * padding.y;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    matrix.x = bounds.x;
Ivan Mahonin b53a5c
    matrix.y = bounds.y;
Ivan Mahonin b53a5c
    matrix.h = bounds.h;
Ivan Mahonin b53a5c
    matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    hue_bar.w = bar_w;
Ivan Mahonin b53a5c
    hue_bar.y = bounds.y;
Ivan Mahonin b53a5c
    hue_bar.h = matrix.h;
Ivan Mahonin b53a5c
    hue_bar.x = matrix.x + matrix.w + padding.x;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
Ivan Mahonin b53a5c
    alpha_bar.y = bounds.y;
Ivan Mahonin b53a5c
    alpha_bar.w = bar_w;
Ivan Mahonin b53a5c
    alpha_bar.h = matrix.h;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
Ivan Mahonin b53a5c
        (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
Ivan Mahonin b53a5c
    nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
Ivan Mahonin b53a5c
    return ret;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_color_pick(struct nk_context * ctx, struct nk_colorf *color,
Ivan Mahonin b53a5c
    enum nk_color_format fmt)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_window *win;
Ivan Mahonin b53a5c
    struct nk_panel *layout;
Ivan Mahonin b53a5c
    const struct nk_style *config;
Ivan Mahonin b53a5c
    const struct nk_input *in;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    enum nk_widget_layout_states state;
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(color);
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 || !color)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    win = ctx->current;
Ivan Mahonin b53a5c
    config = &ctx->style;
Ivan Mahonin b53a5c
    layout = win->layout;
Ivan Mahonin b53a5c
    state = nk_widget(&bounds, ctx);
Ivan Mahonin b53a5c
    if (!state) return 0;
Ivan Mahonin b53a5c
    in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
Ivan Mahonin b53a5c
    return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
Ivan Mahonin b53a5c
                nk_vec2(0,0), in, config->font);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API struct nk_colorf
Ivan Mahonin b53a5c
nk_color_picker(struct nk_context *ctx, struct nk_colorf color,
Ivan Mahonin b53a5c
    enum nk_color_format fmt)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    nk_color_pick(ctx, &color, fmt);
Ivan Mahonin b53a5c
    return color;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c