@@ -28,7 +28,9 @@ NK_API void nk_glfw3_render(enum nk_anti_aliasing);
28
28
NK_API void nk_glfw3_shutdown (void );
29
29
30
30
NK_API void nk_glfw3_char_callback (GLFWwindow * win , unsigned int codepoint );
31
+ NK_API void nk_glfw3_key_callback (GLFWwindow * win , int key , int scancode , int action , int mods );
31
32
NK_API void nk_gflw3_scroll_callback (GLFWwindow * win , double xoff , double yoff );
33
+ NK_API void nk_glfw3_mouse_button_callback (GLFWwindow * window , int button , int action , int mods );
32
34
33
35
#endif
34
36
@@ -74,6 +76,7 @@ static struct nk_glfw {
74
76
struct nk_font_atlas atlas ;
75
77
struct nk_vec2 fb_scale ;
76
78
unsigned int text [NK_GLFW_TEXT_MAX ];
79
+ nk_char key_events [NK_KEY_MAX ];
77
80
int text_len ;
78
81
struct nk_vec2 scroll ;
79
82
double last_button_click ;
@@ -209,6 +212,56 @@ nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
209
212
glfw .text [glfw .text_len ++ ] = codepoint ;
210
213
}
211
214
215
+ NK_API void
216
+ nk_glfw3_key_callback (GLFWwindow * win , int key , int scancode , int action , int mods )
217
+ {
218
+ /*
219
+ * convert GLFW_REPEAT to down (technically GLFW_RELEASE, GLFW_PRESS, GLFW_REPEAT are
220
+ * already 0, 1, 2 but just to be clearer)
221
+ */
222
+ nk_char a = (action == GLFW_RELEASE ) ? nk_false : nk_true ;
223
+
224
+ NK_UNUSED (win );
225
+ NK_UNUSED (scancode );
226
+ NK_UNUSED (mods );
227
+
228
+ switch (key ) {
229
+ case GLFW_KEY_DELETE : glfw .key_events [NK_KEY_DEL ] = a ; break ;
230
+ case GLFW_KEY_TAB : glfw .key_events [NK_KEY_TAB ] = a ; break ;
231
+ case GLFW_KEY_BACKSPACE : glfw .key_events [NK_KEY_BACKSPACE ] = a ; break ;
232
+ case GLFW_KEY_UP : glfw .key_events [NK_KEY_UP ] = a ; break ;
233
+ case GLFW_KEY_DOWN : glfw .key_events [NK_KEY_DOWN ] = a ; break ;
234
+ case GLFW_KEY_LEFT : glfw .key_events [NK_KEY_LEFT ] = a ; break ;
235
+ case GLFW_KEY_RIGHT : glfw .key_events [NK_KEY_RIGHT ] = a ; break ;
236
+
237
+ case GLFW_KEY_PAGE_UP : glfw .key_events [NK_KEY_SCROLL_UP ] = a ; break ;
238
+ case GLFW_KEY_PAGE_DOWN : glfw .key_events [NK_KEY_SCROLL_DOWN ] = a ; break ;
239
+
240
+ /* have to add all keys used for nuklear to get correct repeat behavior
241
+ * NOTE these are scancodes so your custom layout won't matter unfortunately
242
+ * Also while including everything will prevent unnecessary input calls,
243
+ * only the ones with visible effects really matter, ie paste, undo, redo
244
+ * selecting all, copying or cutting 40 times before you release the keys
245
+ * doesn't actually cause any visible problems */
246
+
247
+ case GLFW_KEY_C : glfw .key_events [NK_KEY_COPY ] = a ; break ;
248
+ case GLFW_KEY_V : glfw .key_events [NK_KEY_PASTE ] = a ; break ;
249
+ case GLFW_KEY_X : glfw .key_events [NK_KEY_CUT ] = a ; break ;
250
+ case GLFW_KEY_Z : glfw .key_events [NK_KEY_TEXT_UNDO ] = a ; break ;
251
+ case GLFW_KEY_R : glfw .key_events [NK_KEY_TEXT_REDO ] = a ; break ;
252
+ case GLFW_KEY_B : glfw .key_events [NK_KEY_TEXT_LINE_START ] = a ; break ;
253
+ case GLFW_KEY_E : glfw .key_events [NK_KEY_TEXT_LINE_END ] = a ; break ;
254
+ case GLFW_KEY_A : glfw .key_events [NK_KEY_TEXT_SELECT_ALL ] = a ; break ;
255
+
256
+ case GLFW_KEY_ENTER :
257
+ case GLFW_KEY_KP_ENTER :
258
+ glfw .key_events [NK_KEY_ENTER ] = a ;
259
+ break ;
260
+ default :
261
+ ;
262
+ }
263
+ }
264
+
212
265
NK_API void
213
266
nk_gflw3_scroll_callback (GLFWwindow * win , double xoff , double yoff )
214
267
{
@@ -263,6 +316,7 @@ nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
263
316
if (init_state == NK_GLFW3_INSTALL_CALLBACKS ) {
264
317
glfwSetScrollCallback (win , nk_gflw3_scroll_callback );
265
318
glfwSetCharCallback (win , nk_glfw3_char_callback );
319
+ glfwSetKeyCallback (win , nk_glfw3_key_callback );
266
320
glfwSetMouseButtonCallback (win , nk_glfw3_mouse_button_callback );
267
321
}
268
322
nk_init_default (& glfw .ctx , 0 );
@@ -305,6 +359,7 @@ nk_glfw3_new_frame(void)
305
359
double x , y ;
306
360
struct nk_context * ctx = & glfw .ctx ;
307
361
struct GLFWwindow * win = glfw .win ;
362
+ nk_char * k_state = glfw .key_events ;
308
363
309
364
/* update the timer */
310
365
float delta_time_now = (float )glfwGetTime ();
@@ -326,38 +381,39 @@ nk_glfw3_new_frame(void)
326
381
else if (ctx -> input .mouse .ungrab )
327
382
glfwSetInputMode (glfw .win , GLFW_CURSOR , GLFW_CURSOR_NORMAL );
328
383
329
- nk_input_key (ctx , NK_KEY_DEL , glfwGetKey (win , GLFW_KEY_DELETE ) == GLFW_PRESS );
330
- nk_input_key (ctx , NK_KEY_ENTER , glfwGetKey (win , GLFW_KEY_ENTER ) == GLFW_PRESS ||
331
- glfwGetKey (win , GLFW_KEY_KP_ENTER ) == GLFW_PRESS );
384
+ if (k_state [NK_KEY_DEL ] >= 0 ) nk_input_key (ctx , NK_KEY_DEL , k_state [NK_KEY_DEL ]);
385
+ if (k_state [NK_KEY_ENTER ] >= 0 ) nk_input_key (ctx , NK_KEY_ENTER , k_state [NK_KEY_ENTER ]);
386
+
387
+ if (k_state [NK_KEY_TAB ] >= 0 ) nk_input_key (ctx , NK_KEY_TAB , k_state [NK_KEY_TAB ]);
388
+ if (k_state [NK_KEY_BACKSPACE ] >= 0 ) nk_input_key (ctx , NK_KEY_BACKSPACE , k_state [NK_KEY_BACKSPACE ]);
389
+ if (k_state [NK_KEY_UP ] >= 0 ) nk_input_key (ctx , NK_KEY_UP , k_state [NK_KEY_UP ]);
390
+ if (k_state [NK_KEY_DOWN ] >= 0 ) nk_input_key (ctx , NK_KEY_DOWN , k_state [NK_KEY_DOWN ]);
391
+ if (k_state [NK_KEY_SCROLL_UP ] >= 0 ) nk_input_key (ctx , NK_KEY_SCROLL_UP , k_state [NK_KEY_SCROLL_UP ]);
392
+ if (k_state [NK_KEY_SCROLL_DOWN ] >= 0 ) nk_input_key (ctx , NK_KEY_SCROLL_DOWN , k_state [NK_KEY_SCROLL_DOWN ]);
332
393
333
- nk_input_key (ctx , NK_KEY_TAB , glfwGetKey (win , GLFW_KEY_TAB ) == GLFW_PRESS );
334
- nk_input_key (ctx , NK_KEY_BACKSPACE , glfwGetKey (win , GLFW_KEY_BACKSPACE ) == GLFW_PRESS );
335
- nk_input_key (ctx , NK_KEY_UP , glfwGetKey (win , GLFW_KEY_UP ) == GLFW_PRESS );
336
- nk_input_key (ctx , NK_KEY_DOWN , glfwGetKey (win , GLFW_KEY_DOWN ) == GLFW_PRESS );
337
394
nk_input_key (ctx , NK_KEY_TEXT_START , glfwGetKey (win , GLFW_KEY_HOME ) == GLFW_PRESS );
338
395
nk_input_key (ctx , NK_KEY_TEXT_END , glfwGetKey (win , GLFW_KEY_END ) == GLFW_PRESS );
339
396
nk_input_key (ctx , NK_KEY_SCROLL_START , glfwGetKey (win , GLFW_KEY_HOME ) == GLFW_PRESS );
340
397
nk_input_key (ctx , NK_KEY_SCROLL_END , glfwGetKey (win , GLFW_KEY_END ) == GLFW_PRESS );
341
- nk_input_key (ctx , NK_KEY_SCROLL_DOWN , glfwGetKey (win , GLFW_KEY_PAGE_DOWN ) == GLFW_PRESS );
342
- nk_input_key (ctx , NK_KEY_SCROLL_UP , glfwGetKey (win , GLFW_KEY_PAGE_UP ) == GLFW_PRESS );
343
398
nk_input_key (ctx , NK_KEY_SHIFT , glfwGetKey (win , GLFW_KEY_LEFT_SHIFT ) == GLFW_PRESS ||
344
399
glfwGetKey (win , GLFW_KEY_RIGHT_SHIFT ) == GLFW_PRESS );
345
400
346
401
if (glfwGetKey (win , GLFW_KEY_LEFT_CONTROL ) == GLFW_PRESS ||
347
402
glfwGetKey (win , GLFW_KEY_RIGHT_CONTROL ) == GLFW_PRESS ) {
348
- nk_input_key (ctx , NK_KEY_COPY , glfwGetKey (win , GLFW_KEY_C ) == GLFW_PRESS );
349
- nk_input_key (ctx , NK_KEY_PASTE , glfwGetKey (win , GLFW_KEY_V ) == GLFW_PRESS );
350
- nk_input_key (ctx , NK_KEY_CUT , glfwGetKey (win , GLFW_KEY_X ) == GLFW_PRESS );
351
- nk_input_key (ctx , NK_KEY_TEXT_UNDO , glfwGetKey (win , GLFW_KEY_Z ) == GLFW_PRESS );
352
- nk_input_key (ctx , NK_KEY_TEXT_REDO , glfwGetKey (win , GLFW_KEY_R ) == GLFW_PRESS );
353
- nk_input_key (ctx , NK_KEY_TEXT_WORD_LEFT , glfwGetKey (win , GLFW_KEY_LEFT ) == GLFW_PRESS );
354
- nk_input_key (ctx , NK_KEY_TEXT_WORD_RIGHT , glfwGetKey (win , GLFW_KEY_RIGHT ) == GLFW_PRESS );
355
- nk_input_key (ctx , NK_KEY_TEXT_LINE_START , glfwGetKey (win , GLFW_KEY_B ) == GLFW_PRESS );
356
- nk_input_key (ctx , NK_KEY_TEXT_LINE_END , glfwGetKey (win , GLFW_KEY_E ) == GLFW_PRESS );
357
- nk_input_key (ctx , NK_KEY_TEXT_SELECT_ALL , glfwGetKey (win , GLFW_KEY_A ) == GLFW_PRESS );
403
+ /* Note these are physical keys and won't respect any layouts/key mapping */
404
+ if (k_state [NK_KEY_COPY ] >= 0 ) nk_input_key (ctx , NK_KEY_COPY , k_state [NK_KEY_COPY ]);
405
+ if (k_state [NK_KEY_PASTE ] >= 0 ) nk_input_key (ctx , NK_KEY_PASTE , k_state [NK_KEY_PASTE ]);
406
+ if (k_state [NK_KEY_CUT ] >= 0 ) nk_input_key (ctx , NK_KEY_CUT , k_state [NK_KEY_CUT ]);
407
+ if (k_state [NK_KEY_TEXT_UNDO ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_UNDO , k_state [NK_KEY_TEXT_UNDO ]);
408
+ if (k_state [NK_KEY_TEXT_REDO ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_REDO , k_state [NK_KEY_TEXT_REDO ]);
409
+ if (k_state [NK_KEY_TEXT_LINE_START ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_LINE_START , k_state [NK_KEY_TEXT_LINE_START ]);
410
+ if (k_state [NK_KEY_TEXT_LINE_END ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_LINE_END , k_state [NK_KEY_TEXT_LINE_END ]);
411
+ if (k_state [NK_KEY_TEXT_SELECT_ALL ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_SELECT_ALL , k_state [NK_KEY_TEXT_SELECT_ALL ]);
412
+ if (k_state [NK_KEY_LEFT ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_WORD_LEFT , k_state [NK_KEY_LEFT ]);
413
+ if (k_state [NK_KEY_RIGHT ] >= 0 ) nk_input_key (ctx , NK_KEY_TEXT_WORD_RIGHT , k_state [NK_KEY_RIGHT ]);
358
414
} else {
359
- nk_input_key (ctx , NK_KEY_LEFT , glfwGetKey ( win , GLFW_KEY_LEFT ) == GLFW_PRESS );
360
- nk_input_key (ctx , NK_KEY_RIGHT , glfwGetKey ( win , GLFW_KEY_RIGHT ) == GLFW_PRESS );
415
+ if ( k_state [ NK_KEY_LEFT ] >= 0 ) nk_input_key (ctx , NK_KEY_LEFT , k_state [ NK_KEY_LEFT ] );
416
+ if ( k_state [ NK_KEY_RIGHT ] >= 0 ) nk_input_key (ctx , NK_KEY_RIGHT , k_state [ NK_KEY_RIGHT ] );
361
417
nk_input_key (ctx , NK_KEY_COPY , 0 );
362
418
nk_input_key (ctx , NK_KEY_PASTE , 0 );
363
419
nk_input_key (ctx , NK_KEY_CUT , 0 );
@@ -377,6 +433,10 @@ nk_glfw3_new_frame(void)
377
433
nk_input_button (ctx , NK_BUTTON_DOUBLE , (int )glfw .double_click_pos .x , (int )glfw .double_click_pos .y , glfw .is_double_click_down );
378
434
nk_input_scroll (ctx , glfw .scroll );
379
435
nk_input_end (& glfw .ctx );
436
+
437
+ /* clear after nk_input_end (-1 since we're doing up/down boolean) */
438
+ memset (glfw .key_events , -1 , sizeof (glfw .key_events ));
439
+
380
440
glfw .text_len = 0 ;
381
441
glfw .scroll = nk_vec2 (0 ,0 );
382
442
}
0 commit comments