2017-01-10 9 views
1

В моем SDL 2.0 на основе приложения, я хотел бы обрабатывать как Control +, так и Control =.Как правильно обрабатывать комбинации клавиш управления в SDL2

Я понимаю, что я мог бы обработать событие SDL_KEYDOWN и найти код ключа SDLK_EQUALS в сочетании с KEYMODE_CTRL. И даже проверьте на KEYMOD_SHIFT' to distinguish between + and = `. Однако это не переносимо и ломается на клавиатурах, где эти символы сопоставляются с разными ключами.

Еще одна вещь, которую я пробовал, - включить SDL_StartTextInput(), а затем послушать SDL_TEXTINPUT событий. Однако это работает только для печатных символов. Он полностью игнорирует контрольные последовательности.

Каков правильный способ сделать это? Я вижу SDL 1.2 фактически имел unicode поле в SDL_Keysym структура. Это определенно сделает это намного легче для меня. Кто-нибудь знает, почему это было удалено и что эквивалент в SDL 2.0 будет?

+0

Я думаю, что он был заменен событиями ввода текста, взгляните на https://wiki.libsdl.org/Tutorials/TextInput – keltar

+0

@keltar. Проблема заключается в том, что TextInput проглатывает контрольные клавиши. Он работает только для печатных символов , Я могу прочитать код, чтобы увидеть, как он работает внутри, и, возможно, создать что-то подобное, но я бы предпочел не делать этого. –

+0

Но у вас все еще есть события keydown для ctrl, если он не является частью последовательности ввода, поэтому вы можете комбинировать оба. – keltar

ответ

0

Вот пример того, как вы можете получить юникода ввод как SDL_TEXTINPUT, но остальное, как SDL_KEYDOWN:

#include "SDL.h" 

int main(int argc, char *argv[]) { 
    int done = 0; 
    SDL_Init(SDL_INIT_VIDEO); 
    SDL_Window *w = SDL_CreateWindow("foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
      640, 480, 0); 

    int lctrl = 0, rctrl = 0; 

    SDL_StartTextInput(); 
    while (!done) { 
     SDL_Event event; 
     while(SDL_PollEvent(&event)) { 
      switch (event.type) { 
      case SDL_QUIT: 
       done = 1; 
       break; 
      case SDL_TEXTINPUT: { 
       int ctrl_state = lctrl || rctrl; 
       printf("%s, ctrl %s\n", event.text.text, (ctrl_state) ? "pressed" : "released"); 
      } break; 
      case SDL_KEYDOWN: 
       if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 1; } 
       else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 1; } 
       break; 
      case SDL_KEYUP: 
       if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 0; } 
       else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 0; } 
       break; 
      } 
     } 
     SDL_UpdateWindowSurface(w); 
    } 

    SDL_Quit(); 

    return 0; 
} 

Чтобы упростить вещи, она игнорирует SDL_TEXTEDITING, которые могут (или нет), что вы хотите. Также можно использовать SDL_GetKeyboardState вместо ручной обработки событий и накопления флаги ключей модификатора с тем же результатом.