RobLoach / raylib-nuklear

Nuklear immediate mode GUI for raylib
https://robloach.github.io/raylib-nuklear/
zlib License
151 stars 21 forks source link

Input handling should stop on command #55

Open skinnyjames opened 1 year ago

skinnyjames commented 1 year ago

Noticing when using nk_edit_string that text handling can be a bit erratic.

An example is triggering Select All which is Ctrl + A.
raylib-nuklear correctly processes this input, but also keeps going through the rest of the keys, so what ends up happening for me is

  1. Enter text
  2. Press Ctrl + a
  3. The text is selected, and a is immediately inserted over the selection.

Expected behavior

nk_raylib_input_keyboard returns after an atomic command is captured.

Actual behavior

Commands run in succession unintentionally.

RobLoach commented 8 months ago

Tricky situation... I'm not sure how to handle this. Perhaps we have to switch to typing mode or something? Does raylib have something like that?

skinnyjames commented 8 months ago

@RobLoach I'm not sure what you mean by typing mode, but here is the change to raylib-nuklear.h that I made in my project.

I would strongly encourage to not pull it in, but to consider the strategy while doing what makes sense to this project.

struct check_key {
    int key;
    int input_key;
    bool other;
};

NK_API void nk_raylib_input_keyboard(struct nk_context * ctx)
{
    bool control = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL);
    bool command = IsKeyDown(KEY_LEFT_SUPER);
    bool shift = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
    struct check_key checks[17] = {
        (struct check_key) {KEY_DELETE, NK_KEY_DEL, true},
        (struct check_key) {KEY_ENTER, NK_KEY_ENTER, true},
        (struct check_key) {KEY_BACKSPACE, NK_KEY_BACKSPACE, true},
        (struct check_key) {KEY_C, NK_KEY_COPY, (control || command)},
        (struct check_key) {KEY_V, NK_KEY_PASTE, (control || command)},
        (struct check_key) {KEY_B, NK_KEY_TEXT_LINE_START, (control || command)},
        (struct check_key) {KEY_E, NK_KEY_TEXT_LINE_END, (control || command)},
        (struct check_key) {KEY_Z, NK_KEY_TEXT_UNDO, (control || command)},
        (struct check_key) {KEY_R, NK_KEY_TEXT_REDO, (control || command)},
        (struct check_key) {KEY_A, NK_KEY_TEXT_SELECT_ALL, (control || command)},
        (struct check_key) {KEY_LEFT, NK_KEY_TEXT_WORD_LEFT, (control || command)},
        (struct check_key) {KEY_RIGHT, NK_KEY_TEXT_WORD_RIGHT, (control || command)},
        (struct check_key) {KEY_RIGHT, NK_KEY_RIGHT, true},
        (struct check_key) {KEY_LEFT, NK_KEY_LEFT, true},
        (struct check_key) {KEY_UP, NK_KEY_UP, true},
        (struct check_key) {KEY_DOWN, NK_KEY_DOWN, true}
    };
    bool checked = false;
    for (int i=0; i<12; i++) {
        struct check_key check = checks[i];
        if (IsKeyDown(check.key) && check.other) {
            // printf("key pressed %d\n", i);
            nk_input_key(ctx, check.input_key, true);
            checked = true;
        } else {
            nk_input_key(ctx, check.input_key, false);
        }
    }

    nk_input_key(ctx, NK_KEY_SHIFT, shift);

    if (checked) { 
        return; 
    }

    nk_input_key(ctx, NK_KEY_LEFT, IsKeyDown(KEY_LEFT));
    nk_input_key(ctx, NK_KEY_RIGHT, IsKeyDown(KEY_RIGHT));
    nk_input_key(ctx, NK_KEY_UP, IsKeyDown(KEY_UP));
    nk_input_key(ctx, NK_KEY_DOWN, IsKeyDown(KEY_DOWN));
    nk_input_key(ctx, NK_KEY_TEXT_START, IsKeyDown(KEY_HOME));
    nk_input_key(ctx, NK_KEY_TEXT_END, IsKeyDown(KEY_END));
    nk_input_key(ctx, NK_KEY_SCROLL_START, IsKeyDown(KEY_HOME) && control);
    nk_input_key(ctx, NK_KEY_SCROLL_END, IsKeyDown(KEY_END) && control);
    nk_input_key(ctx, NK_KEY_SCROLL_DOWN, IsKeyDown(KEY_PAGE_DOWN));
    nk_input_key(ctx, NK_KEY_SCROLL_UP, IsKeyDown(KEY_PAGE_UP));

    // Keys
    if (IsKeyPressed(KEY_APOSTROPHE)) nk_input_unicode(ctx, shift ? 34 : (nk_rune)KEY_APOSTROPHE);
    if (IsKeyPressed(KEY_COMMA)) nk_input_unicode(ctx, shift ? 60 : (nk_rune)KEY_COMMA);
    if (IsKeyPressed(KEY_MINUS)) nk_input_unicode(ctx, shift ? 95 : (nk_rune)KEY_MINUS);
    if (IsKeyPressed(KEY_PERIOD)) nk_input_unicode(ctx, shift ? 62 : (nk_rune)KEY_PERIOD);
    if (IsKeyPressed(KEY_SLASH)) nk_input_unicode(ctx, shift ? 63 : (nk_rune)KEY_SLASH);
    if (IsKeyPressed(KEY_ZERO)) nk_input_unicode(ctx, shift ? 41 : (nk_rune)KEY_ZERO);
    if (IsKeyPressed(KEY_ONE)) nk_input_unicode(ctx, shift ? 33 : (nk_rune)KEY_ONE);
    if (IsKeyPressed(KEY_TWO)) nk_input_unicode(ctx, shift ? 64 : (nk_rune)KEY_TWO);
    if (IsKeyPressed(KEY_THREE)) nk_input_unicode(ctx, shift ? 35 : (nk_rune)KEY_THREE);
    if (IsKeyPressed(KEY_FOUR)) nk_input_unicode(ctx, shift ? 36 : (nk_rune)KEY_FOUR);
    if (IsKeyPressed(KEY_FIVE)) nk_input_unicode(ctx, shift ? 37 : (nk_rune)KEY_FIVE);
    if (IsKeyPressed(KEY_SIX)) nk_input_unicode(ctx, shift ? 94 : (nk_rune)KEY_SIX);
    if (IsKeyPressed(KEY_SEVEN)) nk_input_unicode(ctx, shift ? 38 : (nk_rune)KEY_SEVEN);
    if (IsKeyPressed(KEY_EIGHT)) nk_input_unicode(ctx, shift ? 42 : (nk_rune)KEY_EIGHT);
    if (IsKeyPressed(KEY_NINE)) nk_input_unicode(ctx, shift ? 40 : (nk_rune)KEY_NINE);
    if (IsKeyPressed(KEY_SEMICOLON)) nk_input_unicode(ctx, shift ? 41 : (nk_rune)KEY_SEMICOLON);
    if (IsKeyPressed(KEY_EQUAL)) nk_input_unicode(ctx, shift ? 43 : (nk_rune)KEY_EQUAL);
    if (IsKeyPressed(KEY_A)) nk_input_unicode(ctx, shift ? KEY_A : KEY_A + 32);
    if (IsKeyPressed(KEY_B)) nk_input_unicode(ctx, shift ? KEY_B : KEY_B + 32);
    if (IsKeyPressed(KEY_C)) nk_input_unicode(ctx, shift ? KEY_C : KEY_C + 32);
    if (IsKeyPressed(KEY_D)) nk_input_unicode(ctx, shift ? KEY_D : KEY_D + 32);
    if (IsKeyPressed(KEY_E)) nk_input_unicode(ctx, shift ? KEY_E : KEY_E + 32);
    if (IsKeyPressed(KEY_F)) nk_input_unicode(ctx, shift ? KEY_F : KEY_F + 32);
    if (IsKeyPressed(KEY_G)) nk_input_unicode(ctx, shift ? KEY_G : KEY_G + 32);
    if (IsKeyPressed(KEY_H)) nk_input_unicode(ctx, shift ? KEY_H : KEY_H + 32);
    if (IsKeyPressed(KEY_I)) nk_input_unicode(ctx, shift ? KEY_I : KEY_I + 32);
    if (IsKeyPressed(KEY_J)) nk_input_unicode(ctx, shift ? KEY_J : KEY_J + 32);
    if (IsKeyPressed(KEY_K)) nk_input_unicode(ctx, shift ? KEY_K : KEY_K + 32);
    if (IsKeyPressed(KEY_L)) nk_input_unicode(ctx, shift ? KEY_L : KEY_L + 32);
    if (IsKeyPressed(KEY_M)) nk_input_unicode(ctx, shift ? KEY_M : KEY_M + 32);
    if (IsKeyPressed(KEY_N)) nk_input_unicode(ctx, shift ? KEY_N : KEY_N + 32);
    if (IsKeyPressed(KEY_O)) nk_input_unicode(ctx, shift ? KEY_O : KEY_O + 32);
    if (IsKeyPressed(KEY_P)) nk_input_unicode(ctx, shift ? KEY_P : KEY_P + 32);
    if (IsKeyPressed(KEY_Q)) nk_input_unicode(ctx, shift ? KEY_Q : KEY_Q + 32);
    if (IsKeyPressed(KEY_R)) nk_input_unicode(ctx, shift ? KEY_R : KEY_R + 32);
    if (IsKeyPressed(KEY_S)) nk_input_unicode(ctx, shift ? KEY_S : KEY_S + 32);
    if (IsKeyPressed(KEY_T)) nk_input_unicode(ctx, shift ? KEY_T : KEY_T + 32);
    if (IsKeyPressed(KEY_U)) nk_input_unicode(ctx, shift ? KEY_U : KEY_U + 32);
    if (IsKeyPressed(KEY_V)) nk_input_unicode(ctx, shift ? KEY_V : KEY_V + 32);
    if (IsKeyPressed(KEY_W)) nk_input_unicode(ctx, shift ? KEY_W : KEY_W + 32);
    if (IsKeyPressed(KEY_X)) nk_input_unicode(ctx, shift ? KEY_X : KEY_X + 32);
    if (IsKeyPressed(KEY_Y)) nk_input_unicode(ctx, shift ? KEY_Y : KEY_Y + 32);
    if (IsKeyPressed(KEY_Z)) nk_input_unicode(ctx, shift ? KEY_Z : KEY_Z + 32);
    if (IsKeyPressed(KEY_LEFT_BRACKET)) nk_input_unicode(ctx, shift ? 123 : (nk_rune)KEY_LEFT_BRACKET);
    if (IsKeyPressed(KEY_BACKSLASH)) nk_input_unicode(ctx, shift ? 124 : (nk_rune)KEY_BACKSLASH);
    if (IsKeyPressed(KEY_RIGHT_BRACKET)) nk_input_unicode(ctx, shift ? 125 : (nk_rune)KEY_RIGHT_BRACKET);
    if (IsKeyPressed(KEY_GRAVE)) nk_input_unicode(ctx, shift ? 126 : (nk_rune)KEY_GRAVE);

    // Functions
    if (IsKeyPressed(KEY_SPACE)) nk_input_unicode(ctx, KEY_SPACE);
    if (IsKeyPressed(KEY_TAB)) nk_input_unicode(ctx, 9);

    // Keypad
    if (IsKeyPressed(KEY_KP_0)) nk_input_unicode(ctx, KEY_ZERO);
    if (IsKeyPressed(KEY_KP_1)) nk_input_unicode(ctx, KEY_ONE);
    if (IsKeyPressed(KEY_KP_2)) nk_input_unicode(ctx, KEY_TWO);
    if (IsKeyPressed(KEY_KP_3)) nk_input_unicode(ctx, KEY_THREE);
    if (IsKeyPressed(KEY_KP_4)) nk_input_unicode(ctx, KEY_FOUR);
    if (IsKeyPressed(KEY_KP_5)) nk_input_unicode(ctx, KEY_FIVE);
    if (IsKeyPressed(KEY_KP_6)) nk_input_unicode(ctx, KEY_SIX);
    if (IsKeyPressed(KEY_KP_7)) nk_input_unicode(ctx, KEY_SEVEN);
    if (IsKeyPressed(KEY_KP_8)) nk_input_unicode(ctx, KEY_EIGHT);
    if (IsKeyPressed(KEY_KP_9)) nk_input_unicode(ctx, KEY_NINE);
    if (IsKeyPressed(KEY_KP_DECIMAL)) nk_input_unicode(ctx, KEY_PERIOD);
    if (IsKeyPressed(KEY_KP_DIVIDE)) nk_input_unicode(ctx, KEY_SLASH);
    if (IsKeyPressed(KEY_KP_MULTIPLY)) nk_input_unicode(ctx, 48);
    if (IsKeyPressed(KEY_KP_SUBTRACT)) nk_input_unicode(ctx, 45);
    if (IsKeyPressed(KEY_KP_ADD)) nk_input_unicode(ctx, 43);
}