2 #include "nuklear_internal.h" 
   10 nk_drag_behavior(nk_flags *state, 
const struct nk_input *in,
 
   14     int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
 
   15     int left_mouse_click_in_cursor = in &&
 
   16         nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true);
 
   18     nk_widget_state_reset(state);
 
   19     if (nk_input_is_mouse_hovering_rect(in, drag))
 
   22     if (left_mouse_down && left_mouse_click_in_cursor) {
 
   24         pixels = in->mouse.delta.x;
 
   25         delta = pixels * inc_per_pixel;
 
   26         switch (variant->kind) {
 
   29             variant->value.i = variant->value.i + (int)delta;
 
   30             variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
 
   32         case NK_PROPERTY_FLOAT:
 
   33             variant->value.f = variant->value.f + (float)delta;
 
   34             variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
 
   36         case NK_PROPERTY_DOUBLE:
 
   37             variant->value.d = variant->value.d + (double)delta;
 
   38             variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
 
   45     else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
 
   49 nk_property_behavior(nk_flags *ws, 
const struct nk_input *in,
 
   54     nk_widget_state_reset(ws);
 
   55     if (in && *state == NK_PROPERTY_DEFAULT) {
 
   56         if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
 
   57             *state = NK_PROPERTY_EDIT;
 
   58         else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true))
 
   59             *state = NK_PROPERTY_DRAG;
 
   60         else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true))
 
   61             *state = NK_PROPERTY_DRAG;
 
   63     if (*state == NK_PROPERTY_DRAG) {
 
   64         nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
 
   70     const struct nk_rect *bounds, 
const struct nk_rect *label, nk_flags state,
 
   71     const char *name, 
int len, 
const struct nk_user_font *font)
 
   78         background = &style->active;
 
   79         text.text = style->label_active;
 
   81         background = &style->hover;
 
   82         text.text = style->label_hover;
 
   84         background = &style->normal;
 
   85         text.text = style->label_normal;
 
   88     text.text = nk_rgb_factor(text.text, style->color_factor);
 
   91     switch(background->type) {
 
   92         case NK_STYLE_ITEM_IMAGE:
 
   93             text.background = nk_rgba(0, 0, 0, 0);
 
   94             nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor));
 
   96         case NK_STYLE_ITEM_NINE_SLICE:
 
   97             text.background = nk_rgba(0, 0, 0, 0);
 
   98             nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor));
 
  100         case NK_STYLE_ITEM_COLOR:
 
  101             text.background = background->data.color;
 
  102             nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor));
 
  103             nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(background->data.color, style->color_factor));
 
  109     if (name && name[0] != 
'#') {
 
  110         nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
 
  114 nk_do_property(nk_flags *ws,
 
  117     float inc_per_pixel, 
char *buffer, 
int *len,
 
  118     int *state, 
int *cursor, 
int *select_begin, 
int *select_end,
 
  120     enum nk_property_filter filter, 
struct nk_input *in,
 
  122     enum nk_button_behavior behavior)
 
  124     const nk_plugin_filter filters[] = {
 
  129     int num_len = 0, name_len = 0;
 
  130     char string[NK_MAX_NUMBER_BUFFER];
 
  145     left.x = 
property.x + style->border + style->padding.x;
 
  146     left.y = 
property.y + style->border + 
property.h/2.0f - left.h/2;
 
  149     if (name && name[0] != 
'#') {
 
  150         name_len = nk_strlen(name);
 
  152     size = font->
width(font->userdata, font->
height, name, name_len);
 
  153     label.x = left.x + left.w + style->padding.x;
 
  154     label.w = (float)size + 2 * style->padding.x;
 
  155     label.y = property.y + style->border + style->padding.y;
 
  156     label.h = property.h - (2 * style->border + 2 * style->padding.y);
 
  162     right.x = 
property.x + 
property.w - (right.w + style->padding.x);
 
  165     if (*state == NK_PROPERTY_EDIT) {
 
  166         size = font->
width(font->userdata, font->
height, buffer, *len);
 
  167         size += style->edit.cursor_size;
 
  171         switch (variant->kind) {
 
  173         case NK_PROPERTY_INT:
 
  174             nk_itoa(
string, variant->value.i);
 
  175             num_len = nk_strlen(
string);
 
  177         case NK_PROPERTY_FLOAT:
 
  178             NK_DTOA(
string, (
double)variant->value.f);
 
  179             num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
 
  181         case NK_PROPERTY_DOUBLE:
 
  182             NK_DTOA(
string, variant->value.d);
 
  183             num_len = nk_string_float_limit(
string, NK_MAX_FLOAT_PRECISION);
 
  186         size = font->
width(font->userdata, font->
height, 
string, num_len);
 
  191     edit.w =  (float)size + 2 * style->padding.x;
 
  192     edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
 
  193     edit.x = right.x - (edit.w + style->padding.x);
 
  194     edit.y = 
property.y + style->border;
 
  195     edit.h = 
property.h - (2 * style->border);
 
  198     empty.w = edit.x - (label.x + label.w);
 
  199     empty.x = label.x + label.w;
 
  200     empty.y = 
property.y;
 
  201     empty.h = 
property.h;
 
  204     old = (*state == NK_PROPERTY_EDIT);
 
  205     nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
 
  208     if (style->draw_begin) style->draw_begin(out, style->userdata);
 
  209     nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
 
  210     if (style->draw_end) style->draw_end(out, style->userdata);
 
  213     if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
 
  214         switch (variant->kind) {
 
  216         case NK_PROPERTY_INT:
 
  217             variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); 
break;
 
  218         case NK_PROPERTY_FLOAT:
 
  219             variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); 
break;
 
  220         case NK_PROPERTY_DOUBLE:
 
  221             variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); 
break;
 
  225     if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
 
  226         switch (variant->kind) {
 
  228         case NK_PROPERTY_INT:
 
  229             variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); 
break;
 
  230         case NK_PROPERTY_FLOAT:
 
  231             variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); 
break;
 
  232         case NK_PROPERTY_DOUBLE:
 
  233             variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); 
break;
 
  236     if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
 
  238         NK_MEMCPY(buffer, dst, (nk_size)*length);
 
  239         *cursor = nk_utf_len(buffer, *length);
 
  244     } 
else active = (*state == NK_PROPERTY_EDIT);
 
  247     nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
 
  248     text_edit->active = (
unsigned char)active;
 
  249     text_edit->string.len = *length;
 
  250     text_edit->cursor = NK_CLAMP(0, *cursor, *length);
 
  251     text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
 
  252     text_edit->select_end = NK_CLAMP(0,*select_end, *length);
 
  253     text_edit->string.buffer.
allocated = (nk_size)*length;
 
  254     text_edit->string.buffer.
memory.size = NK_MAX_NUMBER_BUFFER;
 
  255     text_edit->string.buffer.
memory.ptr = dst;
 
  256     text_edit->string.buffer.
size = NK_MAX_NUMBER_BUFFER;
 
  257     text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
 
  258     nk_do_edit(ws, out, edit, (
int)NK_EDIT_FIELD|(
int)NK_EDIT_AUTO_SELECT,
 
  259         filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
 
  261     *length = text_edit->string.len;
 
  262     *cursor = text_edit->cursor;
 
  263     *select_begin = text_edit->select_start;
 
  264     *select_end = text_edit->select_end;
 
  265     if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
 
  266         text_edit->active = nk_false;
 
  268     if (active && !text_edit->active) {
 
  270         *state = NK_PROPERTY_DEFAULT;
 
  272         switch (variant->kind) {
 
  274         case NK_PROPERTY_INT:
 
  275             variant->value.i = nk_strtoi(buffer, 0);
 
  276             variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
 
  278         case NK_PROPERTY_FLOAT:
 
  279             nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
 
  280             variant->value.f = nk_strtof(buffer, 0);
 
  281             variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
 
  283         case NK_PROPERTY_DOUBLE:
 
  284             nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
 
  285             variant->value.d = nk_strtod(buffer, 0);
 
  286             variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
 
  292 nk_property_variant_int(int value, int min_value, int max_value, int step)
 
  295     result.kind = NK_PROPERTY_INT;
 
  296     result.value.i = value;
 
  297     result.min_value.i = min_value;
 
  298     result.max_value.i = max_value;
 
  299     result.step.i = step;
 
  303 nk_property_variant_float(float value, float min_value, float max_value, float step)
 
  306     result.kind = NK_PROPERTY_FLOAT;
 
  307     result.value.f = value;
 
  308     result.min_value.f = min_value;
 
  309     result.max_value.f = max_value;
 
  310     result.step.f = step;
 
  314 nk_property_variant_double(double value, double min_value, double max_value,
 
  318     result.kind = NK_PROPERTY_DOUBLE;
 
  319     result.value.d = value;
 
  320     result.min_value.d = min_value;
 
  321     result.max_value.d = max_value;
 
  322     result.step.d = step;
 
  327     float inc_per_pixel, 
const enum nk_property_filter filter)
 
  342     int *select_begin = 0;
 
  346     char dummy_buffer[NK_MAX_NUMBER_BUFFER];
 
  347     int dummy_state = NK_PROPERTY_DEFAULT;
 
  348     int dummy_length = 0;
 
  349     int dummy_cursor = 0;
 
  350     int dummy_select_begin = 0;
 
  351     int dummy_select_end = 0;
 
  354     NK_ASSERT(ctx->current);
 
  355     NK_ASSERT(ctx->current->layout);
 
  356     if (!ctx || !ctx->current || !ctx->current->layout)
 
  360     layout = win->layout;
 
  362     s = nk_widget(&bounds, ctx);
 
  366     if (name[0] == 
'#') {
 
  367         hash = nk_murmur_hash(name, (
int)nk_strlen(name), win->property.seq++);
 
  369     } 
else hash = nk_murmur_hash(name, (
int)nk_strlen(name), 42);
 
  372     if (win->property.active && hash == win->property.name) {
 
  373         buffer = win->property.buffer;
 
  374         len = &win->property.length;
 
  375         cursor = &win->property.cursor;
 
  376         state = &win->property.state;
 
  377         select_begin = &win->property.select_start;
 
  378         select_end = &win->property.select_end;
 
  380         buffer = dummy_buffer;
 
  382         cursor = &dummy_cursor;
 
  383         state = &dummy_state;
 
  384         select_begin =  &dummy_select_begin;
 
  385         select_end = &dummy_select_end;
 
  393     nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
 
  394         variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
 
  395         select_end, &style->property, filter, in, style->font, &ctx->
text_edit,
 
  396         ctx->button_behavior);
 
  398     if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
 
  400         win->property.active = 1;
 
  401         NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
 
  402         win->property.length = *len;
 
  403         win->property.cursor = *cursor;
 
  404         win->property.state = *state;
 
  405         win->property.name = hash;
 
  406         win->property.select_start = *select_begin;
 
  407         win->property.select_end = *select_end;
 
  408         if (*state == NK_PROPERTY_DRAG) {
 
  409             ctx->input.mouse.grab = nk_true;
 
  410             ctx->input.mouse.grabbed = nk_true;
 
  414     if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
 
  415         if (old_state == NK_PROPERTY_DRAG) {
 
  416             ctx->input.mouse.grab = nk_false;
 
  417             ctx->input.mouse.grabbed = nk_false;
 
  418             ctx->input.mouse.ungrab = nk_true;
 
  420         win->property.select_start = 0;
 
  421         win->property.select_end = 0;
 
  422         win->property.active = 0;
 
  426 nk_property_int(
struct nk_context *ctx, 
const char *name,
 
  427     int min, 
int *val, 
int max, 
int step, 
float inc_per_pixel)
 
  434     if (!ctx || !ctx->current || !name || !val) 
return;
 
  435     variant = nk_property_variant_int(*val, min, max, step);
 
  436     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
 
  437     *val = variant.value.i;
 
  441     float min, 
float *val, 
float max, 
float step, 
float inc_per_pixel)
 
  448     if (!ctx || !ctx->current || !name || !val) 
return;
 
  449     variant = nk_property_variant_float(*val, min, max, step);
 
  450     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
 
  451     *val = variant.value.f;
 
  455     double min, 
double *val, 
double max, 
double step, 
float inc_per_pixel)
 
  462     if (!ctx || !ctx->current || !name || !val) 
return;
 
  463     variant = nk_property_variant_double(*val, min, max, step);
 
  464     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
 
  465     *val = variant.value.d;
 
  469     int max, 
int step, 
float inc_per_pixel)
 
  475     if (!ctx || !ctx->current || !name) 
return val;
 
  476     variant = nk_property_variant_int(val, min, max, step);
 
  477     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
 
  478     val = variant.value.i;
 
  483     float val, 
float max, 
float step, 
float inc_per_pixel)
 
  489     if (!ctx || !ctx->current || !name) 
return val;
 
  490     variant = nk_property_variant_float(val, min, max, step);
 
  491     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
 
  492     val = variant.value.f;
 
  497     double val, 
double max, 
double step, 
float inc_per_pixel)
 
  503     if (!ctx || !ctx->current || !name) 
return val;
 
  504     variant = nk_property_variant_double(val, min, max, step);
 
  505     nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
 
  506     val = variant.value.d;
 
main API and documentation file
NK_API float nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel)
NK_API void nk_property_float(struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel)
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
misc
NK_API void nk_property_double(struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel)
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
filled shades
@ NK_WIDGET_STATE_LEFT
!< widget is currently activated
@ NK_WIDGET_STATE_ACTIVED
!< widget is being hovered
@ NK_WIDGET_STATE_ENTERED
!< widget is neither active nor hovered
@ NK_WIDGET_STATE_HOVER
!< widget has been hovered on the current frame
@ NK_WIDGET_STATE_ACTIVE
!< widget is being hovered
@ NK_WIDGET_STATE_HOVERED
!< widget is from this frame on not hovered anymore
@ NK_WIDGET_DISABLED
The widget is manually disabled and acts like NK_WIDGET_ROM.
@ NK_WIDGET_ROM
The widget is partially visible and cannot be updated.
NK_API double nk_propertyd(struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel)
NK_API int nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel)
struct nk_memory memory
!< memory management type
nk_size size
!< number of allocation calls
nk_size allocated
!< growing factor for dynamic memory management
struct nk_text_edit text_edit
text editor objects are quite big because of an internal undo/redo stack.
nk_text_width_f width
!< max height of the font
float height
!< user provided font handle