|
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 |
* POPUP
|
|
Ivan Mahonin |
b53a5c |
*
|
|
Ivan Mahonin |
b53a5c |
* ===============================================================*/
|
|
Ivan Mahonin |
b53a5c |
NK_API nk_bool
|
|
Ivan Mahonin |
b53a5c |
nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
|
|
Ivan Mahonin |
b53a5c |
const char *title, nk_flags flags, struct nk_rect rect)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *win;
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *panel;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
int title_len;
|
|
Ivan Mahonin |
b53a5c |
nk_hash title_hash;
|
|
Ivan Mahonin |
b53a5c |
nk_size allocated;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(ctx);
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(title);
|
|
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 0;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
win = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
panel = win->layout;
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
|
|
Ivan Mahonin |
b53a5c |
(void)panel;
|
|
Ivan Mahonin |
b53a5c |
title_len = (int)nk_strlen(title);
|
|
Ivan Mahonin |
b53a5c |
title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
popup = win->popup.win;
|
|
Ivan Mahonin |
b53a5c |
if (!popup) {
|
|
Ivan Mahonin |
b53a5c |
popup = (struct nk_window*)nk_create_window(ctx);
|
|
Ivan Mahonin |
b53a5c |
popup->parent = win;
|
|
Ivan Mahonin |
b53a5c |
win->popup.win = popup;
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 0;
|
|
Ivan Mahonin |
b53a5c |
win->popup.type = NK_PANEL_POPUP;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
/* make sure we have correct popup */
|
|
Ivan Mahonin |
b53a5c |
if (win->popup.name != title_hash) {
|
|
Ivan Mahonin |
b53a5c |
if (!win->popup.active) {
|
|
Ivan Mahonin |
b53a5c |
nk_zero(popup, sizeof(*popup));
|
|
Ivan Mahonin |
b53a5c |
win->popup.name = title_hash;
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 1;
|
|
Ivan Mahonin |
b53a5c |
win->popup.type = NK_PANEL_POPUP;
|
|
Ivan Mahonin |
b53a5c |
} else return 0;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
/* popup position is local to window */
|
|
Ivan Mahonin |
b53a5c |
ctx->current = popup;
|
|
Ivan Mahonin |
b53a5c |
rect.x += win->layout->clip.x;
|
|
Ivan Mahonin |
b53a5c |
rect.y += win->layout->clip.y;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
/* setup popup data */
|
|
Ivan Mahonin |
b53a5c |
popup->parent = win;
|
|
Ivan Mahonin |
b53a5c |
popup->bounds = rect;
|
|
Ivan Mahonin |
b53a5c |
popup->seq = ctx->seq;
|
|
Ivan Mahonin |
b53a5c |
popup->layout = (struct nk_panel*)nk_create_panel(ctx);
|
|
Ivan Mahonin |
b53a5c |
popup->flags = flags;
|
|
Ivan Mahonin |
b53a5c |
popup->flags |= NK_WINDOW_BORDER;
|
|
Ivan Mahonin |
b53a5c |
if (type == NK_POPUP_DYNAMIC)
|
|
Ivan Mahonin |
b53a5c |
popup->flags |= NK_WINDOW_DYNAMIC;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
popup->buffer = win->buffer;
|
|
Ivan Mahonin |
b53a5c |
nk_start_popup(ctx, win);
|
|
Ivan Mahonin |
b53a5c |
allocated = ctx->memory.allocated;
|
|
Ivan Mahonin |
b53a5c |
nk_push_scissor(&popup->buffer, nk_null_rect);
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
|
|
Ivan Mahonin |
b53a5c |
/* popup is running therefore invalidate parent panels */
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *root;
|
|
Ivan Mahonin |
b53a5c |
root = win->layout;
|
|
Ivan Mahonin |
b53a5c |
while (root) {
|
|
Ivan Mahonin |
b53a5c |
root->flags |= NK_WINDOW_ROM;
|
|
Ivan Mahonin |
b53a5c |
root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
|
|
Ivan Mahonin |
b53a5c |
root = root->parent;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 1;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->offset_x = &popup->scrollbar.x;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->offset_y = &popup->scrollbar.y;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->parent = win->layout;
|
|
Ivan Mahonin |
b53a5c |
return 1;
|
|
Ivan Mahonin |
b53a5c |
} else {
|
|
Ivan Mahonin |
b53a5c |
/* popup was closed/is invalid so cleanup */
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *root;
|
|
Ivan Mahonin |
b53a5c |
root = win->layout;
|
|
Ivan Mahonin |
b53a5c |
while (root) {
|
|
Ivan Mahonin |
b53a5c |
root->flags |= NK_WINDOW_REMOVE_ROM;
|
|
Ivan Mahonin |
b53a5c |
root = root->parent;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
win->popup.buf.active = 0;
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 0;
|
|
Ivan Mahonin |
b53a5c |
ctx->memory.allocated = allocated;
|
|
Ivan Mahonin |
b53a5c |
ctx->current = win;
|
|
Ivan Mahonin |
b53a5c |
nk_free_panel(ctx, popup->layout);
|
|
Ivan Mahonin |
b53a5c |
popup->layout = 0;
|
|
Ivan Mahonin |
b53a5c |
return 0;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
NK_LIB nk_bool
|
|
Ivan Mahonin |
b53a5c |
nk_nonblock_begin(struct nk_context *ctx,
|
|
Ivan Mahonin |
b53a5c |
nk_flags flags, struct nk_rect body, struct nk_rect header,
|
|
Ivan Mahonin |
b53a5c |
enum nk_panel_type panel_type)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *win;
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *panel;
|
|
Ivan Mahonin |
b53a5c |
int is_active = nk_true;
|
|
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 0;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
/* popups cannot have popups */
|
|
Ivan Mahonin |
b53a5c |
win = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
panel = win->layout;
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP));
|
|
Ivan Mahonin |
b53a5c |
(void)panel;
|
|
Ivan Mahonin |
b53a5c |
popup = win->popup.win;
|
|
Ivan Mahonin |
b53a5c |
if (!popup) {
|
|
Ivan Mahonin |
b53a5c |
/* create window for nonblocking popup */
|
|
Ivan Mahonin |
b53a5c |
popup = (struct nk_window*)nk_create_window(ctx);
|
|
Ivan Mahonin |
b53a5c |
popup->parent = win;
|
|
Ivan Mahonin |
b53a5c |
win->popup.win = popup;
|
|
Ivan Mahonin |
b53a5c |
win->popup.type = panel_type;
|
|
Ivan Mahonin |
b53a5c |
nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
|
|
Ivan Mahonin |
b53a5c |
} else {
|
|
Ivan Mahonin |
b53a5c |
/* close the popup if user pressed outside or in the header */
|
|
Ivan Mahonin |
b53a5c |
int pressed, in_body, in_header;
|
|
Ivan Mahonin |
b53a5c |
#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
|
|
Ivan Mahonin |
b53a5c |
pressed = nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT);
|
|
Ivan Mahonin |
b53a5c |
#else
|
|
Ivan Mahonin |
b53a5c |
pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
|
|
Ivan Mahonin |
b53a5c |
#endif
|
|
Ivan Mahonin |
b53a5c |
in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
|
|
Ivan Mahonin |
b53a5c |
in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
|
|
Ivan Mahonin |
b53a5c |
if (pressed && (!in_body || in_header))
|
|
Ivan Mahonin |
b53a5c |
is_active = nk_false;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
win->popup.header = header;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
if (!is_active) {
|
|
Ivan Mahonin |
b53a5c |
/* remove read only mode from all parent panels */
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *root = win->layout;
|
|
Ivan Mahonin |
b53a5c |
while (root) {
|
|
Ivan Mahonin |
b53a5c |
root->flags |= NK_WINDOW_REMOVE_ROM;
|
|
Ivan Mahonin |
b53a5c |
root = root->parent;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
return is_active;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
popup->bounds = body;
|
|
Ivan Mahonin |
b53a5c |
popup->parent = win;
|
|
Ivan Mahonin |
b53a5c |
popup->layout = (struct nk_panel*)nk_create_panel(ctx);
|
|
Ivan Mahonin |
b53a5c |
popup->flags = flags;
|
|
Ivan Mahonin |
b53a5c |
popup->flags |= NK_WINDOW_BORDER;
|
|
Ivan Mahonin |
b53a5c |
popup->flags |= NK_WINDOW_DYNAMIC;
|
|
Ivan Mahonin |
b53a5c |
popup->seq = ctx->seq;
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 1;
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(popup->layout);
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
nk_start_popup(ctx, win);
|
|
Ivan Mahonin |
b53a5c |
popup->buffer = win->buffer;
|
|
Ivan Mahonin |
b53a5c |
nk_push_scissor(&popup->buffer, nk_null_rect);
|
|
Ivan Mahonin |
b53a5c |
ctx->current = popup;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
nk_panel_begin(ctx, 0, panel_type);
|
|
Ivan Mahonin |
b53a5c |
win->buffer = popup->buffer;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->parent = win->layout;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->offset_x = &popup->scrollbar.x;
|
|
Ivan Mahonin |
b53a5c |
popup->layout->offset_y = &popup->scrollbar.y;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
/* set read only mode to all parent panels */
|
|
Ivan Mahonin |
b53a5c |
{struct nk_panel *root;
|
|
Ivan Mahonin |
b53a5c |
root = win->layout;
|
|
Ivan Mahonin |
b53a5c |
while (root) {
|
|
Ivan Mahonin |
b53a5c |
root->flags |= NK_WINDOW_ROM;
|
|
Ivan Mahonin |
b53a5c |
root = root->parent;
|
|
Ivan Mahonin |
b53a5c |
}}
|
|
Ivan Mahonin |
b53a5c |
return is_active;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
NK_API void
|
|
Ivan Mahonin |
b53a5c |
nk_popup_close(struct nk_context *ctx)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(ctx);
|
|
Ivan Mahonin |
b53a5c |
if (!ctx || !ctx->current) return;
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
popup = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(popup->parent);
|
|
Ivan Mahonin |
b53a5c |
NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP);
|
|
Ivan Mahonin |
b53a5c |
popup->flags |= NK_WINDOW_HIDDEN;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
NK_API void
|
|
Ivan Mahonin |
b53a5c |
nk_popup_end(struct nk_context *ctx)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *win;
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
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 |
popup = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
if (!popup->parent) return;
|
|
Ivan Mahonin |
b53a5c |
win = popup->parent;
|
|
Ivan Mahonin |
b53a5c |
if (popup->flags & NK_WINDOW_HIDDEN) {
|
|
Ivan Mahonin |
b53a5c |
struct nk_panel *root;
|
|
Ivan Mahonin |
b53a5c |
root = win->layout;
|
|
Ivan Mahonin |
b53a5c |
while (root) {
|
|
Ivan Mahonin |
b53a5c |
root->flags |= NK_WINDOW_REMOVE_ROM;
|
|
Ivan Mahonin |
b53a5c |
root = root->parent;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
win->popup.active = 0;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
nk_push_scissor(&popup->buffer, nk_null_rect);
|
|
Ivan Mahonin |
b53a5c |
nk_end(ctx);
|
|
Ivan Mahonin |
b53a5c |
|
|
Ivan Mahonin |
b53a5c |
win->buffer = popup->buffer;
|
|
Ivan Mahonin |
b53a5c |
nk_finish_popup(ctx, win);
|
|
Ivan Mahonin |
b53a5c |
ctx->current = win;
|
|
Ivan Mahonin |
b53a5c |
nk_push_scissor(&win->buffer, win->layout->clip);
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
NK_API void
|
|
Ivan Mahonin |
b53a5c |
nk_popup_get_scroll(struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
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 |
popup = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
if (offset_x)
|
|
Ivan Mahonin |
b53a5c |
*offset_x = popup->scrollbar.x;
|
|
Ivan Mahonin |
b53a5c |
if (offset_y)
|
|
Ivan Mahonin |
b53a5c |
*offset_y = popup->scrollbar.y;
|
|
Ivan Mahonin |
b53a5c |
}
|
|
Ivan Mahonin |
b53a5c |
NK_API void
|
|
Ivan Mahonin |
b53a5c |
nk_popup_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
|
|
Ivan Mahonin |
b53a5c |
{
|
|
Ivan Mahonin |
b53a5c |
struct nk_window *popup;
|
|
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 |
popup = ctx->current;
|
|
Ivan Mahonin |
b53a5c |
popup->scrollbar.x = offset_x;
|
|
Ivan Mahonin |
b53a5c |
popup->scrollbar.y = offset_y;
|
|
Ivan Mahonin |
b53a5c |
}
|