| 106 | } |
| 107 | |
| 108 | void TextComposition::HandleMessage(const SDL_Event* e) |
| 109 | { |
| 110 | auto& console = GetInGameConsole(); |
| 111 | |
| 112 | switch (e->type) |
| 113 | { |
| 114 | case SDL_TEXTEDITING: |
| 115 | // When inputting Korean characters, `edit.length` is always zero |
| 116 | String::set(_imeBuffer, sizeof(_imeBuffer), e->edit.text); |
| 117 | _imeStart = e->edit.start; |
| 118 | _imeLength = e->edit.length; |
| 119 | _imeActive = ((e->edit.length != 0 || String::sizeOf(e->edit.text) != 0) && _imeBuffer[0] != '\0'); |
| 120 | break; |
| 121 | case SDL_TEXTINPUT: |
| 122 | // will receive an `SDL_TEXTINPUT` event when a composition is committed |
| 123 | _imeActive = false; |
| 124 | _imeBuffer[0] = '\0'; |
| 125 | if (_session.Buffer != nullptr) |
| 126 | { |
| 127 | // HACK ` will close console, so don't input any text |
| 128 | if (e->text.text[0] == '`' && console.IsOpen()) |
| 129 | { |
| 130 | break; |
| 131 | } |
| 132 | |
| 133 | Insert(e->text.text); |
| 134 | |
| 135 | console.RefreshCaret(_session.SelectionStart); |
| 136 | Windows::WindowUpdateTextbox(); |
| 137 | } |
| 138 | break; |
| 139 | case SDL_KEYDOWN: |
| 140 | { |
| 141 | if (_imeActive) |
| 142 | { |
| 143 | break; |
| 144 | } |
| 145 | |
| 146 | uint16_t modifier = e->key.keysym.mod; |
| 147 | SDL_Keycode rawKey = e->key.keysym.sym; |
| 148 | SDL_Scancode rawScancode = e->key.keysym.scancode; |
| 149 | |
| 150 | auto [key, scancode] = ProcessKeyPress(rawKey, rawScancode); |
| 151 | |
| 152 | GetContext()->GetUiContext().SetKeysPressed(key, scancode); |
| 153 | |
| 154 | // Text input |
| 155 | if (_session.Buffer == nullptr) |
| 156 | { |
| 157 | break; |
| 158 | } |
| 159 | |
| 160 | switch (key) |
| 161 | { |
| 162 | case SDLK_BACKSPACE: |
| 163 | // If backspace and we have input text with a cursor position nonzero |
| 164 | if (_session.SelectionStart > 0) |
| 165 | { |
no test coverage detected