f5aa92c5ca
Nuklear now comes in two flavours. For ones there is the single-header version for distribution and multiple files inside the /src folder for development and better readability. Since I don't want to manually update each version if the other changes the /src directory includes a python script developed by Apoorva Joshi to pack all files inside the directory into a single header file.
296 lines
9.6 KiB
C
296 lines
9.6 KiB
C
#include "nuklear.h"
|
|
#include "nuklear_internal.h"
|
|
|
|
/* ===============================================================
|
|
*
|
|
* MENU
|
|
*
|
|
* ===============================================================*/
|
|
NK_API void
|
|
nk_menubar_begin(struct nk_context *ctx)
|
|
{
|
|
struct nk_panel *layout;
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return;
|
|
|
|
layout = ctx->current->layout;
|
|
NK_ASSERT(layout->at_y == layout->bounds.y);
|
|
/* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
|
|
If you want a menubar the first nuklear function after `nk_begin` has to be a
|
|
`nk_menubar_begin` call. Inside the menubar you then have to allocate space for
|
|
widgets (also supports multiple rows).
|
|
Example:
|
|
if (nk_begin(...)) {
|
|
nk_menubar_begin(...);
|
|
nk_layout_xxxx(...);
|
|
nk_button(...);
|
|
nk_layout_xxxx(...);
|
|
nk_button(...);
|
|
nk_menubar_end(...);
|
|
}
|
|
nk_end(...);
|
|
*/
|
|
if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
|
|
return;
|
|
|
|
layout->menu.x = layout->at_x;
|
|
layout->menu.y = layout->at_y + layout->row.height;
|
|
layout->menu.w = layout->bounds.w;
|
|
layout->menu.offset.x = *layout->offset_x;
|
|
layout->menu.offset.y = *layout->offset_y;
|
|
*layout->offset_y = 0;
|
|
}
|
|
NK_API void
|
|
nk_menubar_end(struct nk_context *ctx)
|
|
{
|
|
struct nk_window *win;
|
|
struct nk_panel *layout;
|
|
struct nk_command_buffer *out;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return;
|
|
|
|
win = ctx->current;
|
|
out = &win->buffer;
|
|
layout = win->layout;
|
|
if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
|
|
return;
|
|
|
|
layout->menu.h = layout->at_y - layout->menu.y;
|
|
layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
|
|
layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
|
|
|
|
*layout->offset_x = layout->menu.offset.x;
|
|
*layout->offset_y = layout->menu.offset.y;
|
|
layout->at_y = layout->bounds.y - layout->row.height;
|
|
|
|
layout->clip.y = layout->bounds.y;
|
|
layout->clip.h = layout->bounds.h;
|
|
nk_push_scissor(out, layout->clip);
|
|
}
|
|
NK_INTERN int
|
|
nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
|
|
const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
|
|
{
|
|
int is_open = 0;
|
|
int is_active = 0;
|
|
struct nk_rect body;
|
|
struct nk_window *popup;
|
|
nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
body.x = header.x;
|
|
body.w = size.x;
|
|
body.y = header.y + header.h;
|
|
body.h = size.y;
|
|
|
|
popup = win->popup.win;
|
|
is_open = popup ? nk_true : nk_false;
|
|
is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
|
|
if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
|
|
(!is_open && !is_active && !is_clicked)) return 0;
|
|
if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
|
|
return 0;
|
|
|
|
win->popup.type = NK_PANEL_MENU;
|
|
win->popup.name = hash;
|
|
return 1;
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
|
|
nk_flags align, struct nk_vec2 size)
|
|
{
|
|
struct nk_window *win;
|
|
const struct nk_input *in;
|
|
struct nk_rect header;
|
|
int is_clicked = nk_false;
|
|
nk_flags state;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
win = ctx->current;
|
|
state = nk_widget(&header, ctx);
|
|
if (!state) return 0;
|
|
in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
|
if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
|
|
title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
|
|
is_clicked = nk_true;
|
|
return nk_menu_begin(ctx, win, title, is_clicked, header, size);
|
|
}
|
|
NK_API int nk_menu_begin_label(struct nk_context *ctx,
|
|
const char *text, nk_flags align, struct nk_vec2 size)
|
|
{
|
|
return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
|
|
struct nk_vec2 size)
|
|
{
|
|
struct nk_window *win;
|
|
struct nk_rect header;
|
|
const struct nk_input *in;
|
|
int is_clicked = nk_false;
|
|
nk_flags state;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
win = ctx->current;
|
|
state = nk_widget(&header, ctx);
|
|
if (!state) return 0;
|
|
in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
|
if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
|
|
img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
|
|
is_clicked = nk_true;
|
|
return nk_menu_begin(ctx, win, id, is_clicked, header, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
|
|
enum nk_symbol_type sym, struct nk_vec2 size)
|
|
{
|
|
struct nk_window *win;
|
|
const struct nk_input *in;
|
|
struct nk_rect header;
|
|
int is_clicked = nk_false;
|
|
nk_flags state;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
win = ctx->current;
|
|
state = nk_widget(&header, ctx);
|
|
if (!state) return 0;
|
|
in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
|
if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
|
|
sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
|
|
is_clicked = nk_true;
|
|
return nk_menu_begin(ctx, win, id, is_clicked, header, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
|
|
nk_flags align, struct nk_image img, struct nk_vec2 size)
|
|
{
|
|
struct nk_window *win;
|
|
struct nk_rect header;
|
|
const struct nk_input *in;
|
|
int is_clicked = nk_false;
|
|
nk_flags state;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
win = ctx->current;
|
|
state = nk_widget(&header, ctx);
|
|
if (!state) return 0;
|
|
in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
|
if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
|
|
header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
|
|
ctx->style.font, in))
|
|
is_clicked = nk_true;
|
|
return nk_menu_begin(ctx, win, title, is_clicked, header, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_image_label(struct nk_context *ctx,
|
|
const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
|
|
{
|
|
return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
|
|
nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
|
|
{
|
|
struct nk_window *win;
|
|
struct nk_rect header;
|
|
const struct nk_input *in;
|
|
int is_clicked = nk_false;
|
|
nk_flags state;
|
|
|
|
NK_ASSERT(ctx);
|
|
NK_ASSERT(ctx->current);
|
|
NK_ASSERT(ctx->current->layout);
|
|
if (!ctx || !ctx->current || !ctx->current->layout)
|
|
return 0;
|
|
|
|
win = ctx->current;
|
|
state = nk_widget(&header, ctx);
|
|
if (!state) return 0;
|
|
|
|
in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
|
if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
|
|
header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
|
|
ctx->style.font, in)) is_clicked = nk_true;
|
|
return nk_menu_begin(ctx, win, title, is_clicked, header, size);
|
|
}
|
|
NK_API int
|
|
nk_menu_begin_symbol_label(struct nk_context *ctx,
|
|
const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
|
|
{
|
|
return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
|
|
}
|
|
NK_API int
|
|
nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
|
|
{
|
|
return nk_contextual_item_text(ctx, title, len, align);
|
|
}
|
|
NK_API int
|
|
nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
|
|
{
|
|
return nk_contextual_item_label(ctx, label, align);
|
|
}
|
|
NK_API int
|
|
nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
|
|
const char *label, nk_flags align)
|
|
{
|
|
return nk_contextual_item_image_label(ctx, img, label, align);
|
|
}
|
|
NK_API int
|
|
nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
|
|
const char *text, int len, nk_flags align)
|
|
{
|
|
return nk_contextual_item_image_text(ctx, img, text, len, align);
|
|
}
|
|
NK_API int nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
|
|
const char *text, int len, nk_flags align)
|
|
{
|
|
return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
|
|
}
|
|
NK_API int nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
|
|
const char *label, nk_flags align)
|
|
{
|
|
return nk_contextual_item_symbol_label(ctx, sym, label, align);
|
|
}
|
|
NK_API void nk_menu_close(struct nk_context *ctx)
|
|
{
|
|
nk_contextual_close(ctx);
|
|
}
|
|
NK_API void
|
|
nk_menu_end(struct nk_context *ctx)
|
|
{
|
|
nk_contextual_end(ctx);
|
|
}
|
|
|