浏览代码

Fix GLFW repeat behavior correctly this time

Robert Winkler 7 月之前
父节点
当前提交
a2af701759
共有 2 个文件被更改,包括 82 次插入14 次删除
  1. 1 1
      demo/glfw_opengl3/main.c
  2. 81 13
      demo/glfw_opengl3/nuklear_glfw_gl3.h

+ 1 - 1
demo/glfw_opengl3/main.c

@@ -21,7 +21,7 @@
 #define NK_INCLUDE_DEFAULT_FONT
 #define NK_IMPLEMENTATION
 #define NK_GLFW_GL3_IMPLEMENTATION
-#define NK_KEYSTATE_BASED_INPUT
+/*#define NK_KEYSTATE_BASED_INPUT */
 #include "../../nuklear.h"
 #include "nuklear_glfw_gl3.h"
 

+ 81 - 13
demo/glfw_opengl3/nuklear_glfw_gl3.h

@@ -48,6 +48,7 @@ struct nk_glfw {
     struct nk_font_atlas atlas;
     struct nk_vec2 fb_scale;
     unsigned int text[NK_GLFW_TEXT_MAX];
+    char key_events[NK_KEY_MAX];
     int text_len;
     struct nk_vec2 scroll;
     double last_button_click;
@@ -320,6 +321,66 @@ nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
         glfw->text[glfw->text_len++] = codepoint;
 }
 
+
+NK_API void
+nk_glfw3_key_callback(GLFWwindow *win, int key, int scancode, int action, int mods)
+{
+    struct nk_glfw* glfw = (struct nk_glfw *)glfwGetWindowUserPointer(win);
+    char a = (action == GLFW_RELEASE) ? nk_false : nk_true;
+
+    NK_UNUSED(scancode);
+    NK_UNUSED(mods);
+    /* convert GLFW_REPEAT to down (technically GLFW_RELEASE and GLFW_PRESS are
+    // already 0 and 1 but just to be clearer
+    //int a = (action == GLFW_RELEASE) ? GLFW_RELEASE : GLFW_PRESS;
+    */
+
+    switch (key) {
+    case GLFW_KEY_DELETE:    glfw->key_events[NK_KEY_DEL] = a; break;
+    case GLFW_KEY_TAB:       glfw->key_events[NK_KEY_TAB] = a; break;
+    case GLFW_KEY_BACKSPACE: glfw->key_events[NK_KEY_BACKSPACE] = a; break;
+    case GLFW_KEY_UP:        glfw->key_events[NK_KEY_UP] = a; break;
+    case GLFW_KEY_DOWN:      glfw->key_events[NK_KEY_DOWN] = a; break;
+    case GLFW_KEY_LEFT:      glfw->key_events[NK_KEY_LEFT] = a; break;
+    case GLFW_KEY_RIGHT:     glfw->key_events[NK_KEY_RIGHT] = a; break;
+
+    case GLFW_KEY_PAGE_UP:   glfw->key_events[NK_KEY_SCROLL_UP] = a; break;
+    case GLFW_KEY_PAGE_DOWN: glfw->key_events[NK_KEY_SCROLL_DOWN] = a; break;
+
+    case GLFW_KEY_ENTER:
+    case GLFW_KEY_KP_ENTER:
+        glfw->key_events[NK_KEY_ENTER] = a;
+        break;
+    default:
+        ;
+    }
+
+/*
+    // If I think repeats are really likely to happen multiple times per frame
+    if (action == GLFW_REPEAT) {
+        switch (key) {
+        case GLFW_KEY_DEL:       glfw->key_clicks[NK_KEY_DEL]++; break;
+        case GLFW_KEY_TAB:       glfw->key_clicks[NK_KEY_TAB]++; break;
+        case GLFW_KEY_BACKSPACE: glfw->key_clicks[NK_KEY_BACKSPACE]++; break;
+        case GLFW_KEY_UP:        glfw->key_clicks[NK_KEY_UP]++; break;
+        case GLFW_KEY_DOWN:      glfw->key_clicks[NK_KEY_DOWN]++; break;
+        case GLFW_KEY_LEFT:      glfw->key_clicks[NK_KEY_LEFT]++; break;
+        case GLFW_KEY_RIGHT:     glfw->key_clicks[NK_KEY_RIGHT]++; break;
+
+        case GLFW_KEY_PAGE_UP:   glfw->key_clicks[NK_KEY_SCROLL_UP]++; break;
+        case GLFW_KEY_PAGE_DOWN: glfw->key_clicks[NK_KEY_SCROLL_DOWN]++; break;
+
+        case GLFW_KEY_ENTER:
+        case GLFW_KEY_KP_ENTER:
+            glfw->key_clicks[NK_KEY_DEL]++;
+            break;
+        default:
+            ;
+        }
+    }
+*/
+}
+
 NK_API void
 nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
 {
@@ -378,6 +439,7 @@ nk_glfw3_init(struct nk_glfw* glfw, GLFWwindow *win, enum nk_glfw_init_state ini
     if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
         glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
         glfwSetCharCallback(win, nk_glfw3_char_callback);
+        glfwSetKeyCallback(win, nk_glfw3_key_callback);
         glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
     }
     nk_init_default(&glfw->ctx, 0);
@@ -421,6 +483,7 @@ nk_glfw3_new_frame(struct nk_glfw* glfw)
     double x, y;
     struct nk_context *ctx = &glfw->ctx;
     struct GLFWwindow *win = glfw->win;
+    char* k_state = glfw->key_events;
 
     /* update the timer */
     float delta_time_now = (float)glfwGetTime();
@@ -444,38 +507,39 @@ nk_glfw3_new_frame(struct nk_glfw* glfw)
         glfwSetInputMode(glfw->win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
 #endif
 
-    nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS ||
-                                    glfwGetKey(win, GLFW_KEY_KP_ENTER) == GLFW_PRESS);
+    if (k_state[NK_KEY_DEL] >= 0) nk_input_key(ctx, NK_KEY_DEL, k_state[NK_KEY_DEL]);
+    if (k_state[NK_KEY_ENTER] >= 0) nk_input_key(ctx, NK_KEY_ENTER, k_state[NK_KEY_ENTER]);
+
+    if (k_state[NK_KEY_TAB] >= 0) nk_input_key(ctx, NK_KEY_TAB, k_state[NK_KEY_TAB]);
+    if (k_state[NK_KEY_BACKSPACE] >= 0) nk_input_key(ctx, NK_KEY_BACKSPACE, k_state[NK_KEY_BACKSPACE]);
+    if (k_state[NK_KEY_UP] >= 0) nk_input_key(ctx, NK_KEY_UP, k_state[NK_KEY_UP]);
+    if (k_state[NK_KEY_DOWN] >= 0) nk_input_key(ctx, NK_KEY_DOWN, k_state[NK_KEY_DOWN]);
+    if (k_state[NK_KEY_SCROLL_UP] >= 0) nk_input_key(ctx, NK_KEY_SCROLL_UP, k_state[NK_KEY_SCROLL_UP]);
+    if (k_state[NK_KEY_SCROLL_DOWN] >= 0) nk_input_key(ctx, NK_KEY_SCROLL_DOWN, k_state[NK_KEY_SCROLL_DOWN]);
 
-    nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
     nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
     nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
     nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
     nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
-    nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
     nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
                                     glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
 
     if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
         glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
+        /* Note these are physical keys and won't respect any layouts/key mapping */
         nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
-        nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
-        nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
         nk_input_key(ctx, NK_KEY_TEXT_SELECT_ALL, glfwGetKey(win, GLFW_KEY_A) == GLFW_PRESS);
+        if (k_state[NK_KEY_LEFT] >= 0) nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, k_state[NK_KEY_LEFT]);
+        if (k_state[NK_KEY_RIGHT] >= 0) nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, k_state[NK_KEY_RIGHT]);
     } else {
-        nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
-        nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
+        if (k_state[NK_KEY_LEFT] >= 0) nk_input_key(ctx, NK_KEY_LEFT, k_state[NK_KEY_LEFT]);
+        if (k_state[NK_KEY_RIGHT] >= 0) nk_input_key(ctx, NK_KEY_RIGHT, k_state[NK_KEY_RIGHT]);
         nk_input_key(ctx, NK_KEY_COPY, 0);
         nk_input_key(ctx, NK_KEY_PASTE, 0);
         nk_input_key(ctx, NK_KEY_CUT, 0);
@@ -496,6 +560,10 @@ nk_glfw3_new_frame(struct nk_glfw* glfw)
     nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw->double_click_pos.x, (int)glfw->double_click_pos.y, glfw->is_double_click_down);
     nk_input_scroll(ctx, glfw->scroll);
     nk_input_end(&glfw->ctx);
+
+    /* clear after nk_input_end *(-1 since we're doing up/down boolean, 0 if I do clicks */
+    memset(glfw->key_events, -1, sizeof(glfw->key_events));
+
     glfw->text_len = 0;
     glfw->scroll = nk_vec2(0,0);
 }