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.
nuklear_input.c
1 #include "nuklear.h"
2 #include "nuklear_internal.h"
3 
4 /* ===============================================================
5  *
6  * INPUT
7  *
8  * ===============================================================*/
9 NK_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 }
29 NK_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 }
44 NK_API void
45 nk_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 }
56 NK_API void
57 nk_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 }
71 NK_API void
72 nk_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 }
98 NK_API void
99 nk_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 }
106 NK_API void
107 nk_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 }
124 NK_API void
125 nk_input_char(struct nk_context *ctx, char c)
126 {
127  nk_glyph glyph;
128  NK_ASSERT(ctx);
129  if (!ctx) return;
130  glyph[0] = c;
131  nk_input_glyph(ctx, glyph);
132 }
133 NK_API void
134 nk_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 }
142 NK_API nk_bool
143 nk_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 }
150 NK_API nk_bool
151 nk_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 }
161 NK_API nk_bool
162 nk_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 }
177 NK_API nk_bool
178 nk_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 }
186 NK_API nk_bool
187 nk_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 }
196 NK_API nk_bool
197 nk_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 }
206 NK_API nk_bool
207 nk_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 }
214 NK_API nk_bool
215 nk_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 }
220 NK_API nk_bool
221 nk_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 }
226 NK_API nk_bool
227 nk_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 }
233 NK_API nk_bool
234 nk_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 }
239 NK_API nk_bool
240 nk_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 }
249 NK_API nk_bool
250 nk_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 }
255 NK_API nk_bool
256 nk_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 }
265 NK_API nk_bool
266 nk_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 }
275 NK_API nk_bool
276 nk_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...
Definition: nuklear_input.c:30
NK_API void nk_input_begin(struct nk_context *)
Begins the input mirroring process by resetting text, scroll mouse, previous mouse position and movem...
Definition: nuklear_input.c:10
#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.
Definition: nuklear_input.c:57
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.
Definition: nuklear_input.c:72
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.
Definition: nuklear_input.c:99
NK_API void nk_input_motion(struct nk_context *, int x, int y)
Mirrors current mouse position to nuklear.
Definition: nuklear_input.c:45
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.