Nuklear
This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.
 
Loading...
Searching...
No Matches
nuklear_input.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ===============================================================
5 *
6 * INPUT
7 *
8 * ===============================================================*/
9NK_API void
11{
12 int i;
13 struct nk_input *in;
14 NK_ASSERT(ctx);
15 if (!ctx) return;
16 in = &ctx->input;
17 for (i = 0; i < NK_BUTTON_MAX; ++i)
18 in->mouse.buttons[i].clicked = 0;
19
20 in->keyboard.text_len = 0;
21 in->mouse.scroll_delta = nk_vec2(0,0);
22 in->mouse.prev.x = in->mouse.pos.x;
23 in->mouse.prev.y = in->mouse.pos.y;
24 in->mouse.delta.x = 0;
25 in->mouse.delta.y = 0;
26 for (i = 0; i < NK_KEY_MAX; i++)
27 in->keyboard.keys[i].clicked = 0;
28}
29NK_API void
31{
32 struct nk_input *in;
33 NK_ASSERT(ctx);
34 if (!ctx) return;
35 in = &ctx->input;
36 if (in->mouse.grab)
37 in->mouse.grab = 0;
38 if (in->mouse.ungrab) {
39 in->mouse.grabbed = 0;
40 in->mouse.ungrab = 0;
41 in->mouse.grab = 0;
42 }
43}
44NK_API void
45nk_input_motion(struct nk_context *ctx, int x, int y)
46{
47 struct nk_input *in;
48 NK_ASSERT(ctx);
49 if (!ctx) return;
50 in = &ctx->input;
51 in->mouse.pos.x = (float)x;
52 in->mouse.pos.y = (float)y;
53 in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
54 in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
55}
56NK_API void
57nk_input_key(struct nk_context *ctx, enum nk_keys key, nk_bool down)
58{
59 struct nk_input *in;
60 NK_ASSERT(ctx);
61 if (!ctx) return;
62 in = &ctx->input;
63#ifdef NK_KEYSTATE_BASED_INPUT
64 if (in->keyboard.keys[key].down != down)
65 in->keyboard.keys[key].clicked++;
66#else
67 in->keyboard.keys[key].clicked++;
68#endif
69 in->keyboard.keys[key].down = down;
70}
71NK_API void
72nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, nk_bool down)
73{
74 struct nk_mouse_button *btn;
75 struct nk_input *in;
76 NK_ASSERT(ctx);
77 if (!ctx) return;
78 in = &ctx->input;
79 if (in->mouse.buttons[id].down == down) return;
80
81 btn = &in->mouse.buttons[id];
82 btn->clicked_pos.x = (float)x;
83 btn->clicked_pos.y = (float)y;
84 btn->down = down;
85 btn->clicked++;
86
87 /* Fix Click-Drag for touch events. */
88 in->mouse.delta.x = 0;
89 in->mouse.delta.y = 0;
90#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
91 if (down == 1 && id == NK_BUTTON_LEFT)
92 {
93 in->mouse.down_pos.x = btn->clicked_pos.x;
94 in->mouse.down_pos.y = btn->clicked_pos.y;
95 }
96#endif
97}
98NK_API void
99nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val)
100{
101 NK_ASSERT(ctx);
102 if (!ctx) return;
103 ctx->input.mouse.scroll_delta.x += val.x;
104 ctx->input.mouse.scroll_delta.y += val.y;
105}
106NK_API void
107nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph)
108{
109 int len = 0;
110 nk_rune unicode;
111 struct nk_input *in;
112
113 NK_ASSERT(ctx);
114 if (!ctx) return;
115 in = &ctx->input;
116
117 len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE);
118 if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
119 nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
120 NK_INPUT_MAX - in->keyboard.text_len);
121 in->keyboard.text_len += len;
122 }
123}
124NK_API void
125nk_input_char(struct nk_context *ctx, char c)
126{
127 nk_glyph glyph = {0};
128 NK_ASSERT(ctx);
129 if (!ctx) return;
130 glyph[0] = c;
131 nk_input_glyph(ctx, glyph);
132}
133NK_API void
134nk_input_unicode(struct nk_context *ctx, nk_rune unicode)
135{
136 nk_glyph rune;
137 NK_ASSERT(ctx);
138 if (!ctx) return;
139 nk_utf_encode(unicode, rune, NK_UTF_SIZE);
140 nk_input_glyph(ctx, rune);
141}
142NK_API nk_bool
143nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id)
144{
145 const struct nk_mouse_button *btn;
146 if (!i) return nk_false;
147 btn = &i->mouse.buttons[id];
148 return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
149}
150NK_API nk_bool
151nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
152 struct nk_rect b)
153{
154 const struct nk_mouse_button *btn;
155 if (!i) return nk_false;
156 btn = &i->mouse.buttons[id];
157 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
158 return nk_false;
159 return nk_true;
160}
161NK_API nk_bool
162nk_input_has_mouse_click_in_button_rect(const struct nk_input *i, enum nk_buttons id,
163 struct nk_rect b)
164{
165 const struct nk_mouse_button *btn;
166 if (!i) return nk_false;
167 btn = &i->mouse.buttons[id];
168#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
169 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h)
170 || !NK_INBOX(i->mouse.down_pos.x,i->mouse.down_pos.y,b.x,b.y,b.w,b.h))
171#else
172 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
173#endif
174 return nk_false;
175 return nk_true;
176}
177NK_API nk_bool
178nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id,
179 struct nk_rect b, nk_bool down)
180{
181 const struct nk_mouse_button *btn;
182 if (!i) return nk_false;
183 btn = &i->mouse.buttons[id];
184 return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down);
185}
186NK_API nk_bool
187nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
188 struct nk_rect b)
189{
190 const struct nk_mouse_button *btn;
191 if (!i) return nk_false;
192 btn = &i->mouse.buttons[id];
193 return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) &&
194 btn->clicked) ? nk_true : nk_false;
195}
196NK_API nk_bool
197nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id,
198 struct nk_rect b, nk_bool down)
199{
200 const struct nk_mouse_button *btn;
201 if (!i) return nk_false;
202 btn = &i->mouse.buttons[id];
203 return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) &&
204 btn->clicked) ? nk_true : nk_false;
205}
206NK_API nk_bool
207nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b)
208{
209 int i, down = 0;
210 for (i = 0; i < NK_BUTTON_MAX; ++i)
211 down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b);
212 return down;
213}
214NK_API nk_bool
215nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
216{
217 if (!i) return nk_false;
218 return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
219}
220NK_API nk_bool
221nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
222{
223 if (!i) return nk_false;
224 return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
225}
226NK_API nk_bool
227nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect)
228{
229 if (!i) return nk_false;
230 if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false;
231 return nk_input_is_mouse_click_in_rect(i, id, rect);
232}
233NK_API nk_bool
234nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
235{
236 if (!i) return nk_false;
237 return i->mouse.buttons[id].down;
238}
239NK_API nk_bool
240nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
241{
242 const struct nk_mouse_button *b;
243 if (!i) return nk_false;
244 b = &i->mouse.buttons[id];
245 if (b->down && b->clicked)
246 return nk_true;
247 return nk_false;
248}
249NK_API nk_bool
250nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
251{
252 if (!i) return nk_false;
253 return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked);
254}
255NK_API nk_bool
256nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
257{
258 const struct nk_key *k;
259 if (!i) return nk_false;
260 k = &i->keyboard.keys[key];
261 if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
262 return nk_true;
263 return nk_false;
264}
265NK_API nk_bool
266nk_input_is_key_released(const struct nk_input *i, enum nk_keys key)
267{
268 const struct nk_key *k;
269 if (!i) return nk_false;
270 k = &i->keyboard.keys[key];
271 if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
272 return nk_true;
273 return nk_false;
274}
275NK_API nk_bool
276nk_input_is_key_down(const struct nk_input *i, enum nk_keys key)
277{
278 const struct nk_key *k;
279 if (!i) return nk_false;
280 k = &i->keyboard.keys[key];
281 if (k->down) return nk_true;
282 return nk_false;
283}
284
main API and documentation file
NK_API void nk_input_end(struct nk_context *)
End the input mirroring process by resetting mouse grabbing state to ensure the mouse cursor is not g...
NK_API void nk_input_begin(struct nk_context *)
Begins the input mirroring process by resetting text, scroll mouse, previous mouse position and movem...
#define NK_UTF_SIZE
describes the number of bytes a glyph consists of
Definition nuklear.h:22
NK_API void nk_input_unicode(struct nk_context *, nk_rune)
Converts a unicode rune into UTF-8 and copies the result into an internal text buffer.
NK_API void nk_input_key(struct nk_context *, enum nk_keys, nk_bool down)
Mirrors the state of a specific key to nuklear.
NK_API void nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, nk_bool down)
Mirrors the state of a specific mouse button to nuklear.
NK_API void nk_input_char(struct nk_context *, char)
Copies a single ASCII character into an internal text buffer.
NK_API void nk_input_scroll(struct nk_context *, struct nk_vec2 val)
Copies the last mouse scroll value to nuklear.
NK_API void nk_input_motion(struct nk_context *, int x, int y)
Mirrors current mouse position to nuklear.
NK_API void nk_input_glyph(struct nk_context *, const nk_glyph)
Converts an encoded unicode rune into UTF-8 and copies the result into an internal text buffer.