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