文本编辑器的键盘输入

Keyboard input for a text editor

我正在制作一个文本编辑器,它通过 SDL2 使用 OpenGL 进行渲染。我正在使用 SDL_K switch 语句来获取键盘输入:

if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) {
    should_run = 0;
    break;
}
else if (event.type == SDL_KEYDOWN)
{
    switch (event.key.keysym.sym)
    {
        case SDLK_a:
        add_character(&test_element, 'a');
        break;

        case SDLK_b:
        add_character(&test_element, 'b');
        break;

        case SDLK_c:
        add_character(&test_element, 'c');
        break;

        case SDLK_d:
        add_character(&test_element, 'd');
        break;

        case SDLK_LEFT:
        move_cursor(&test_element, -1);
        break;

        case SDLK_RIGHT:
        move_cursor(&test_element, 1);
        break;

    }
}

整个键盘,我都会有两个写很多switch case。有更好的方法吗?

是的,有更好的方法。使用 SDL_TextInputEvent,它将为您提供用户输入的任何内容的 UTF-8 表示形式。

好的,我查看了 SDLKey 值:https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkey.html

它们实际上是各自字符的 ascii 值,所以我可以将 event.key.keysim.sim 直接输入到我的 add_character 函数中,如果我在上一帧:

int kbshift = 0;
for (should_run = 1; should_run; ) {

    if (timer_diff > FRAME_TIME){
        timer_start = clock();

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) {
                should_run = 0;
                break;
            }
            else if (event.type == SDL_KEYDOWN)
            {
                if (event.key.keysym.sym >= 32 && event.key.keysym.sym <= 127)
                {
                    if (kbshift)
                        add_character(&test_element, event.key.keysym.sym - 32);
                    else
                        add_character(&test_element, event.key.keysym.sym);
                }
                switch (event.key.keysym.sym)
                {
                    case SDLK_LSHIFT:
                    kbshift = 1;
                    break;

                    case SDLK_LEFT:
                    move_cursor(&test_element, -1);
                    break;

                    case SDLK_RIGHT:
                    move_cursor(&test_element, 1);
                    break;

                }
            }
            else if (event.type == SDL_KEYUP)
            {
                switch (event.key.keysym.sym)
                {
                    case SDLK_LSHIFT:
                    kbshift = 0;
                    break;
                }
            }
        }

        Update();
    }

    timer_end = clock();
    timer_diff = ((double) (timer_end - timer_start)) / CLOCKS_PER_SEC;
}

另外,感谢 HolyBlackCat。对于 utf-8 渲染,我将不得不重新考虑我的字体纹理,它目前是一个 16x16 字符的 ascii 网格。快速 google 搜索表明 utf-8 可以支持 1,112,064 个唯一字符。 sqrt(1,112,064) = 1054.54445141,因此 1055x1055 字符网格应该可以正常工作。假设我们使用所有正方形 5x5 像素字符,我们最终的字体纹理将是边长 1055*5 像素——也就是说,我们最终的字体纹理将是 5275x5275 像素。我们必须检查的最后一件事是 5x5px 字符是否为我们提供了足够的组合。如果我们的像素只能是黑色或白色,那就是 2^25 个可能的 5x5px 图像,或 33,554,432,这是 utf-8 支持的图像的 33 倍。如果完整的 5275x5275 像素纹理对于 GPU 来说太多了,我可以将它分成 2637x2637 像素象限等等。