| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- #include "nuklear.h"
- #include "nuklear_internal.h"
- /* ==============================================================
- *
- * CONTEXT
- *
- * ===============================================================*/
- NK_INTERN void
- nk_setup(struct nk_context *ctx, const struct nk_user_font *font)
- {
- NK_ASSERT(ctx);
- if (!ctx) return;
- nk_zero_struct(*ctx);
- nk_style_default(ctx);
- ctx->seq = 1;
- if (font) ctx->style.font = font;
- #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
- nk_draw_list_init(&ctx->draw_list);
- #endif
- }
- #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
- NK_API nk_bool
- nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
- {
- struct nk_allocator alloc;
- alloc.userdata.ptr = 0;
- alloc.alloc = nk_malloc;
- alloc.free = nk_mfree;
- return nk_init(ctx, &alloc, font);
- }
- #endif
- NK_API nk_bool
- nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size,
- const struct nk_user_font *font)
- {
- NK_ASSERT(memory);
- if (!memory) return 0;
- nk_setup(ctx, font);
- nk_buffer_init_fixed(&ctx->memory, memory, size);
- ctx->use_pool = nk_false;
- return 1;
- }
- NK_API nk_bool
- nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
- struct nk_buffer *pool, const struct nk_user_font *font)
- {
- NK_ASSERT(cmds);
- NK_ASSERT(pool);
- if (!cmds || !pool) return 0;
- nk_setup(ctx, font);
- ctx->memory = *cmds;
- if (pool->type == NK_BUFFER_FIXED) {
- /* take memory from buffer and alloc fixed pool */
- nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size);
- } else {
- /* create dynamic pool from buffer allocator */
- struct nk_allocator *alloc = &pool->pool;
- nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
- }
- ctx->use_pool = nk_true;
- return 1;
- }
- NK_API nk_bool
- nk_init(struct nk_context *ctx, const struct nk_allocator *alloc,
- const struct nk_user_font *font)
- {
- NK_ASSERT(alloc);
- if (!alloc) return 0;
- nk_setup(ctx, font);
- nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
- nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
- ctx->use_pool = nk_true;
- return 1;
- }
- #ifdef NK_INCLUDE_COMMAND_USERDATA
- NK_API void
- nk_set_user_data(struct nk_context *ctx, nk_handle handle)
- {
- if (!ctx) return;
- ctx->userdata = handle;
- if (ctx->current)
- ctx->current->buffer.userdata = handle;
- }
- #endif
- NK_API void
- nk_free(struct nk_context *ctx)
- {
- NK_ASSERT(ctx);
- if (!ctx) return;
- nk_buffer_free(&ctx->memory);
- if (ctx->use_pool)
- nk_pool_free(&ctx->pool);
- nk_zero(&ctx->input, sizeof(ctx->input));
- nk_zero(&ctx->style, sizeof(ctx->style));
- nk_zero(&ctx->memory, sizeof(ctx->memory));
- ctx->seq = 0;
- ctx->build = 0;
- ctx->begin = 0;
- ctx->end = 0;
- ctx->active = 0;
- ctx->current = 0;
- ctx->freelist = 0;
- ctx->count = 0;
- }
- NK_API void
- nk_clear(struct nk_context *ctx)
- {
- struct nk_window *iter;
- struct nk_window *next;
- NK_ASSERT(ctx);
- if (!ctx) return;
- if (ctx->use_pool)
- nk_buffer_clear(&ctx->memory);
- else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
- ctx->build = 0;
- ctx->memory.calls = 0;
- ctx->last_widget_state = 0;
- ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
- NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay));
- /* garbage collector */
- iter = ctx->begin;
- while (iter) {
- /* make sure valid minimized windows do not get removed */
- if ((iter->flags & NK_WINDOW_MINIMIZED) &&
- !(iter->flags & NK_WINDOW_CLOSED) &&
- iter->seq == ctx->seq) {
- iter = iter->next;
- continue;
- }
- /* remove hotness from hidden or closed windows*/
- if (((iter->flags & NK_WINDOW_HIDDEN) ||
- (iter->flags & NK_WINDOW_CLOSED)) &&
- iter == ctx->active) {
- ctx->active = iter->prev;
- ctx->end = iter->prev;
- if (!ctx->end)
- ctx->begin = 0;
- if (ctx->active)
- ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
- }
- /* free unused popup windows */
- if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
- nk_free_window(ctx, iter->popup.win);
- iter->popup.win = 0;
- }
- /* remove unused window state tables */
- {struct nk_table *n, *it = iter->tables;
- while (it) {
- n = it->next;
- if (it->seq != ctx->seq) {
- nk_remove_table(iter, it);
- nk_zero(it, sizeof(union nk_page_data));
- nk_free_table(ctx, it);
- if (it == iter->tables)
- iter->tables = n;
- } it = n;
- }}
- /* window itself is not used anymore so free */
- if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
- next = iter->next;
- nk_remove_window(ctx, iter);
- nk_free_window(ctx, iter);
- iter = next;
- } else iter = iter->next;
- }
- ctx->seq++;
- }
- NK_LIB void
- nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
- {
- NK_ASSERT(ctx);
- NK_ASSERT(buffer);
- if (!ctx || !buffer) return;
- buffer->begin = ctx->memory.allocated;
- buffer->end = buffer->begin;
- buffer->last = buffer->begin;
- buffer->clip = nk_null_rect;
- }
- NK_LIB void
- nk_start(struct nk_context *ctx, struct nk_window *win)
- {
- NK_ASSERT(ctx);
- NK_ASSERT(win);
- nk_start_buffer(ctx, &win->buffer);
- }
- NK_LIB void
- nk_start_popup(struct nk_context *ctx, struct nk_window *win)
- {
- struct nk_popup_buffer *buf;
- NK_ASSERT(ctx);
- NK_ASSERT(win);
- if (!ctx || !win) return;
- /* save buffer fill state for popup */
- buf = &win->popup.buf;
- buf->begin = win->buffer.end;
- buf->end = win->buffer.end;
- buf->parent = win->buffer.last;
- buf->last = buf->begin;
- buf->active = nk_true;
- }
- NK_LIB void
- nk_finish_popup(struct nk_context *ctx, struct nk_window *win)
- {
- struct nk_popup_buffer *buf;
- NK_ASSERT(ctx);
- NK_ASSERT(win);
- if (!ctx || !win) return;
- buf = &win->popup.buf;
- buf->last = win->buffer.last;
- buf->end = win->buffer.end;
- }
- NK_LIB void
- nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
- {
- NK_ASSERT(ctx);
- NK_ASSERT(buffer);
- if (!ctx || !buffer) return;
- buffer->end = ctx->memory.allocated;
- }
- NK_LIB void
- nk_finish(struct nk_context *ctx, struct nk_window *win)
- {
- struct nk_popup_buffer *buf;
- struct nk_command *parent_last;
- void *memory;
- NK_ASSERT(ctx);
- NK_ASSERT(win);
- if (!ctx || !win) return;
- nk_finish_buffer(ctx, &win->buffer);
- if (!win->popup.buf.active) return;
- buf = &win->popup.buf;
- memory = ctx->memory.memory.ptr;
- parent_last = nk_ptr_add(struct nk_command, memory, buf->parent);
- parent_last->next = buf->end;
- }
- NK_LIB void
- nk_build(struct nk_context *ctx)
- {
- struct nk_window *it = 0;
- struct nk_command *cmd = 0;
- nk_byte *buffer = 0;
- /* draw cursor overlay */
- if (!ctx->style.cursor_active)
- ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
- if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
- struct nk_rect mouse_bounds;
- const struct nk_cursor *cursor = ctx->style.cursor_active;
- nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF);
- nk_start_buffer(ctx, &ctx->overlay);
- mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
- mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
- mouse_bounds.w = cursor->size.x;
- mouse_bounds.h = cursor->size.y;
- nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white);
- nk_finish_buffer(ctx, &ctx->overlay);
- }
- /* build one big draw command list out of all window buffers */
- it = ctx->begin;
- buffer = (nk_byte*)ctx->memory.memory.ptr;
- while (it != 0) {
- struct nk_window *next = it->next;
- if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
- it->seq != ctx->seq)
- goto cont;
- cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
- while (next && ((next->buffer.last == next->buffer.begin) ||
- (next->flags & NK_WINDOW_HIDDEN) || next->seq != ctx->seq))
- next = next->next; /* skip empty command buffers */
- if (next) cmd->next = next->buffer.begin;
- cont: it = next;
- }
- /* append all popup draw commands into lists */
- it = ctx->begin;
- while (it != 0) {
- struct nk_window *next = it->next;
- struct nk_popup_buffer *buf;
- if (!it->popup.buf.active)
- goto skip;
- buf = &it->popup.buf;
- cmd->next = buf->begin;
- cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
- buf->active = nk_false;
- skip: it = next;
- }
- if (cmd) {
- /* append overlay commands */
- if (ctx->overlay.end != ctx->overlay.begin)
- cmd->next = ctx->overlay.begin;
- else cmd->next = ctx->memory.allocated;
- }
- }
- NK_API const struct nk_command*
- nk__begin(struct nk_context *ctx)
- {
- struct nk_window *iter;
- nk_byte *buffer;
- NK_ASSERT(ctx);
- if (!ctx) return 0;
- if (!ctx->count) return 0;
- buffer = (nk_byte*)ctx->memory.memory.ptr;
- if (!ctx->build) {
- nk_build(ctx);
- ctx->build = nk_true;
- }
- iter = ctx->begin;
- while (iter && ((iter->buffer.begin == iter->buffer.end) ||
- (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
- iter = iter->next;
- if (!iter) return 0;
- return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
- }
- NK_API const struct nk_command*
- nk__next(struct nk_context *ctx, const struct nk_command *cmd)
- {
- nk_byte *buffer;
- const struct nk_command *next;
- NK_ASSERT(ctx);
- if (!ctx || !cmd || !ctx->count) return 0;
- if (cmd->next >= ctx->memory.allocated) return 0;
- buffer = (nk_byte*)ctx->memory.memory.ptr;
- next = nk_ptr_add_const(struct nk_command, buffer, cmd->next);
- return next;
- }
|