diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 5826b4a61b..7df90f652c 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -374,6 +374,11 @@ struct IConsoleWindow : Window this->Scroll(-wheel); } + virtual void OnFocus(Window *previously_focused_window) override + { + VideoDriver::GetInstance()->EditBoxGainedFocus(); + } + void OnFocusLost(Window *newly_focused_window) override { VideoDriver::GetInstance()->EditBoxLostFocus(); diff --git a/src/textbuf.cpp b/src/textbuf.cpp index 3847575661..066a1277f3 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -101,6 +101,7 @@ bool Textbuf::DeleteChar(uint16 keycode) /* Move the remaining characters over the marker */ memmove(s, s + len, this->bytes - (s - this->buf) - len); this->bytes -= len; + if (this->markend >= this->bytes) this->markpos = this->markend = 0; if (backspace) this->caretpos -= len; @@ -251,6 +252,7 @@ void Textbuf::DeleteText(uint16 from, uint16 to, bool update) /* Strip marked characters from buffer. */ memmove(this->buf + from, this->buf + to, this->bytes - to); this->bytes -= to - from; + if (this->markend >= this->bytes) this->markpos = this->markend = 0; this->chars -= c; /* Fixup caret if needed. */ diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 36fc03c387..0d6c9534a9 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -23,6 +23,7 @@ #include "../core/math_func.hpp" #include "../fileio_func.h" #include "../framerate_type.h" +#include "../window_func.h" #include "sdl2_v.h" #include #include @@ -60,6 +61,8 @@ static int _num_dirty_rects; static int _window_size_w; static int _window_size_h; +static std::string _editing_text; + void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height) { if (_num_dirty_rects < MAX_DIRTY_RECTS) { @@ -358,6 +361,18 @@ bool VideoDriver_SDL::ClaimMousePointer() return true; } +void VideoDriver_SDL::EditBoxGainedFocus() +{ + SDL_StartTextInput(); +} + +void VideoDriver_SDL::EditBoxLostFocus() +{ + SDL_StopTextInput(); + /* Clear any marked string from the current edit box. */ + HandleTextInput(nullptr, true); +} + struct VkMapping { SDL_Keycode vk_from; byte vk_count; @@ -574,6 +589,11 @@ int VideoDriver_SDL::PollEvent() break; case SDL_TEXTINPUT: { + if (EditBoxInGlobalFocus()) { + HandleTextInput(nullptr, true); + HandleTextInput(ev.text.text); + break; + } WChar character; SDL_Keycode kc = SDL_GetKeyFromName(ev.text.text); uint keycode = ConvertSdlKeycodeIntoMy(kc); @@ -582,6 +602,18 @@ int VideoDriver_SDL::PollEvent() HandleKeypress(keycode, character); break; } + + case SDL_TEXTEDITING: { + if (!EditBoxInGlobalFocus()) break; + if (ev.edit.start == 0) { + _editing_text = ev.edit.text; + } else { + _editing_text += ev.edit.text; + } + HandleTextInput(_editing_text.c_str(), true, _editing_text.c_str() + _editing_text.size()); + break; + } + case SDL_WINDOWEVENT: { if (ev.window.event == SDL_WINDOWEVENT_EXPOSED) { // Force a redraw of the entire screen. diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index ba7e322ed3..8612ccbadc 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -37,6 +37,10 @@ public: bool ClaimMousePointer() override; + void EditBoxGainedFocus() override; + + void EditBoxLostFocus() override; + const char *GetName() const override { return "sdl"; } private: int PollEvent(); diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index b774c7ba6e..869839b485 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -88,6 +88,11 @@ public: return true; } + /** + * An edit box gained the input focus + */ + virtual void EditBoxGainedFocus() {} + /** * An edit box lost the input focus. Abort character compositing if necessary. */ diff --git a/src/window.cpp b/src/window.cpp index fe7b00c937..220f7ca15f 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -502,11 +502,20 @@ bool Window::SetFocusedWidget(int widget_index) if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus(); } this->nested_focus = this->GetWidget(widget_index); + if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxGainedFocus(); return true; } /** - * Called when window looses focus + * Called when window gains focus + */ +void Window::OnFocus(Window *previously_focused_window) +{ + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxGainedFocus(); +} + +/** + * Called when window loses focus */ void Window::OnFocusLost(Window *newly_focused_window) { diff --git a/src/window_gui.h b/src/window_gui.h index 636c06e3fd..b79d617395 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -645,7 +645,7 @@ public: * Called when window gains focus * @param previously_focused_window The window that lost the focus. */ - virtual void OnFocus(Window *previously_focused_window) {} + virtual void OnFocus(Window *previously_focused_window); virtual void OnFocusLost(Window *newly_focused_window);