Blame src-nuklear/nuklear_widget.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
 *                              WIDGET
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * ===============================================================*/
Ivan Mahonin b53a5c
NK_API struct nk_rect
Ivan Mahonin b53a5c
nk_widget_bounds(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current)
Ivan Mahonin b53a5c
        return nk_rect(0,0,0,0);
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    return bounds;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API struct nk_vec2
Ivan Mahonin b53a5c
nk_widget_position(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current)
Ivan Mahonin b53a5c
        return nk_vec2(0,0);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    return nk_vec2(bounds.x, bounds.y);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API struct nk_vec2
Ivan Mahonin b53a5c
nk_widget_size(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current)
Ivan Mahonin b53a5c
        return nk_vec2(0,0);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    return nk_vec2(bounds.w, bounds.h);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API float
Ivan Mahonin b53a5c
nk_widget_width(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    return bounds.w;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API float
Ivan Mahonin b53a5c
nk_widget_height(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    return bounds.h;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_widget_is_hovered(struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect c, v;
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current || ctx->active != ctx->current)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    c = ctx->current->layout->clip;
Ivan Mahonin b53a5c
    c.x = (float)((int)c.x);
Ivan Mahonin b53a5c
    c.y = (float)((int)c.y);
Ivan Mahonin b53a5c
    c.w = (float)((int)c.w);
Ivan Mahonin b53a5c
    c.h = (float)((int)c.h);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
Ivan Mahonin b53a5c
    if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
    return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect c, v;
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current || ctx->active != ctx->current)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    c = ctx->current->layout->clip;
Ivan Mahonin b53a5c
    c.x = (float)((int)c.x);
Ivan Mahonin b53a5c
    c.y = (float)((int)c.y);
Ivan Mahonin b53a5c
    c.w = (float)((int)c.w);
Ivan Mahonin b53a5c
    c.h = (float)((int)c.h);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
Ivan Mahonin b53a5c
    if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
    return nk_input_mouse_clicked(&ctx->input, btn, bounds);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API nk_bool
Ivan Mahonin b53a5c
nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, nk_bool down)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect c, v;
Ivan Mahonin b53a5c
    struct nk_rect bounds;
Ivan Mahonin b53a5c
    NK_ASSERT(ctx);
Ivan Mahonin b53a5c
    NK_ASSERT(ctx->current);
Ivan Mahonin b53a5c
    if (!ctx || !ctx->current || ctx->active != ctx->current)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    c = ctx->current->layout->clip;
Ivan Mahonin b53a5c
    c.x = (float)((int)c.x);
Ivan Mahonin b53a5c
    c.y = (float)((int)c.y);
Ivan Mahonin b53a5c
    c.w = (float)((int)c.w);
Ivan Mahonin b53a5c
    c.h = (float)((int)c.h);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_layout_peek(&bounds, ctx);
Ivan Mahonin b53a5c
    nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
Ivan Mahonin b53a5c
    if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
    return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API enum nk_widget_layout_states
Ivan Mahonin b53a5c
nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_rect c, v;
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
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 NK_WIDGET_INVALID;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* allocate space and check if the widget needs to be updated and drawn */
Ivan Mahonin b53a5c
    nk_panel_alloc_space(bounds, ctx);
Ivan Mahonin b53a5c
    win = ctx->current;
Ivan Mahonin b53a5c
    layout = win->layout;
Ivan Mahonin b53a5c
    in = &ctx->input;
Ivan Mahonin b53a5c
    c = layout->clip;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /*  if one of these triggers you forgot to add an `if` condition around either
Ivan Mahonin b53a5c
        a window, group, popup, combobox or contextual menu `begin` and `end` block.
Ivan Mahonin b53a5c
        Example:
Ivan Mahonin b53a5c
            if (nk_begin(...) {...} nk_end(...); or
Ivan Mahonin b53a5c
            if (nk_group_begin(...) { nk_group_end(...);} */
Ivan Mahonin b53a5c
    NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
Ivan Mahonin b53a5c
    NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
Ivan Mahonin b53a5c
    NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* need to convert to int here to remove floating point errors */
Ivan Mahonin b53a5c
    bounds->x = (float)((int)bounds->x);
Ivan Mahonin b53a5c
    bounds->y = (float)((int)bounds->y);
Ivan Mahonin b53a5c
    bounds->w = (float)((int)bounds->w);
Ivan Mahonin b53a5c
    bounds->h = (float)((int)bounds->h);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    c.x = (float)((int)c.x);
Ivan Mahonin b53a5c
    c.y = (float)((int)c.y);
Ivan Mahonin b53a5c
    c.w = (float)((int)c.w);
Ivan Mahonin b53a5c
    c.h = (float)((int)c.h);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
Ivan Mahonin b53a5c
    if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
Ivan Mahonin b53a5c
        return NK_WIDGET_INVALID;
Ivan Mahonin b53a5c
    if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
Ivan Mahonin b53a5c
        return NK_WIDGET_ROM;
Ivan Mahonin b53a5c
    return NK_WIDGET_VALID;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API enum nk_widget_layout_states
Ivan Mahonin b53a5c
nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
Ivan Mahonin b53a5c
    struct nk_vec2 item_padding)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    /* update the bounds to stand without padding  */
Ivan Mahonin b53a5c
    enum nk_widget_layout_states state;
Ivan Mahonin b53a5c
    NK_UNUSED(item_padding);
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 NK_WIDGET_INVALID;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    state = nk_widget(bounds, ctx);
Ivan Mahonin b53a5c
    return state;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API void
Ivan Mahonin b53a5c
nk_spacing(struct nk_context *ctx, int cols)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    struct nk_window *win;
Ivan Mahonin b53a5c
    struct nk_panel *layout;
Ivan Mahonin b53a5c
    struct nk_rect none;
Ivan Mahonin b53a5c
    int i, index, rows;
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;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    /* spacing over row boundaries */
Ivan Mahonin b53a5c
    win = ctx->current;
Ivan Mahonin b53a5c
    layout = win->layout;
Ivan Mahonin b53a5c
    index = (layout->row.index + cols) % layout->row.columns;
Ivan Mahonin b53a5c
    rows = (layout->row.index + cols) / layout->row.columns;
Ivan Mahonin b53a5c
    if (rows) {
Ivan Mahonin b53a5c
        for (i = 0; i < rows; ++i)
Ivan Mahonin b53a5c
            nk_panel_alloc_row(ctx, win);
Ivan Mahonin b53a5c
        cols = index;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    /* non table layout need to allocate space */
Ivan Mahonin b53a5c
    if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
Ivan Mahonin b53a5c
        layout->row.type != NK_LAYOUT_STATIC_FIXED) {
Ivan Mahonin b53a5c
        for (i = 0; i < cols; ++i)
Ivan Mahonin b53a5c
            nk_panel_alloc_space(&none, ctx);
Ivan Mahonin b53a5c
    } layout->row.index = index;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c