diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/gui/sdl/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/platform/gui/sdl/InputMethod.cpp | 66 | ||||
| -rw-r--r-- | src/platform/gui/sdl/UiApplication.cpp | 36 | ||||
| -rw-r--r-- | src/platform/gui/sdl/Window.cpp | 41 |
4 files changed, 109 insertions, 35 deletions
diff --git a/src/platform/gui/sdl/CMakeLists.txt b/src/platform/gui/sdl/CMakeLists.txt index fac9d859..c01e8bbf 100644 --- a/src/platform/gui/sdl/CMakeLists.txt +++ b/src/platform/gui/sdl/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(CruPlatformGuiSdl Base.cpp Cursor.cpp Input.cpp + InputMethod.cpp UiApplication.cpp Window.cpp ) diff --git a/src/platform/gui/sdl/InputMethod.cpp b/src/platform/gui/sdl/InputMethod.cpp new file mode 100644 index 00000000..0cd22544 --- /dev/null +++ b/src/platform/gui/sdl/InputMethod.cpp @@ -0,0 +1,66 @@ +#include "cru/platform/gui/sdl/InputMethod.h" +#include "SDL3/SDL_events.h" +#include "cru/platform/gui/sdl/Base.h" +#include "cru/platform/gui/sdl/Window.h" + +#include <SDL3/SDL_keyboard.h> + +namespace cru::platform::gui::sdl { +SdlInputMethodContext::SdlInputMethodContext(SdlWindow* window) + : window_(window) {} + +bool SdlInputMethodContext::ShouldManuallyDrawCompositionText() { + return false; +} + +void SdlInputMethodContext::EnableIME() { + if (auto sdl_window = window_->GetSdlWindow()) { + CheckSdlReturn(SDL_StartTextInput(sdl_window)); + } +} +void SdlInputMethodContext::DisableIME() { + if (auto sdl_window = window_->GetSdlWindow()) { + CheckSdlReturn(SDL_StopTextInput(sdl_window)); + } +} + +void SdlInputMethodContext::CompleteComposition() { CancelComposition(); } + +void SdlInputMethodContext::CancelComposition() { + if (auto sdl_window = window_->GetSdlWindow()) { + CheckSdlReturn(SDL_ClearComposition(sdl_window)); + } +} + +CompositionText SdlInputMethodContext::GetCompositionText() { return {}; } + +void SdlInputMethodContext::SetCandidateWindowPosition(const Point& point) { + if (auto sdl_window = window_->GetSdlWindow()) { + SDL_Rect rect{static_cast<int>(point.x), static_cast<int>(point.y), 1, 1}; + CheckSdlReturn(SDL_SetTextInputArea(sdl_window, &rect, 0)); + } +} + +namespace { +std::optional<SDL_WindowID> GetEventWindowId(const SDL_Event& event) { + switch (event.type) { + case SDL_EVENT_TEXT_INPUT: + return event.text.windowID; + default: + return std::nullopt; + } +} +} // namespace + +bool SdlInputMethodContext::HandleEvent(const SDL_Event* event) { + if (window_->GetSdlWindowId() != GetEventWindowId(*event)) return false; + + if (event->type == SDL_EVENT_TEXT_INPUT) { + std::string text(event->text.text); + TextEvent_.Raise(text); + return true; + } + return false; +} + +} // namespace cru::platform::gui::sdl diff --git a/src/platform/gui/sdl/UiApplication.cpp b/src/platform/gui/sdl/UiApplication.cpp index d2275a37..6d52b5f7 100644 --- a/src/platform/gui/sdl/UiApplication.cpp +++ b/src/platform/gui/sdl/UiApplication.cpp @@ -157,40 +157,10 @@ long long SdlUiApplication::SetTimer(std::chrono::milliseconds milliseconds, return timers_.Add(std::move(action), milliseconds, repeat); } -namespace { -std::optional<SDL_WindowID> GetEventWindowId(const SDL_Event& event) { - switch (event.type) { - case SDL_EVENT_WINDOW_MOVED: - case SDL_EVENT_WINDOW_RESIZED: - case SDL_EVENT_WINDOW_SHOWN: - case SDL_EVENT_WINDOW_HIDDEN: - case SDL_EVENT_WINDOW_MINIMIZED: - case SDL_EVENT_WINDOW_FOCUS_GAINED: - case SDL_EVENT_WINDOW_FOCUS_LOST: - case SDL_EVENT_WINDOW_MOUSE_ENTER: - case SDL_EVENT_WINDOW_MOUSE_LEAVE: - case SDL_EVENT_WINDOW_DESTROYED: - return event.window.windowID; - case SDL_EVENT_MOUSE_BUTTON_DOWN: - case SDL_EVENT_MOUSE_BUTTON_UP: - return event.button.windowID; - case SDL_EVENT_MOUSE_WHEEL: - return event.wheel.windowID; - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_KEY_UP: - return event.key.windowID; - default: - return std::nullopt; - } -} -} // namespace - bool SdlUiApplication::DispatchEvent(const SDL_Event& event) { - if (auto window_id = GetEventWindowId(event)) { - for (auto window : windows_) { - if (window->sdl_window_id_ == *window_id && window->HandleEvent(&event)) { - return true; - } + for (auto window : windows_) { + if (window->HandleEvent(&event)) { + return true; } } return false; diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp index f4b0422e..a4dea5ad 100644 --- a/src/platform/gui/sdl/Window.cpp +++ b/src/platform/gui/sdl/Window.cpp @@ -8,6 +8,7 @@ #include "cru/platform/gui/sdl/Base.h" #include "cru/platform/gui/sdl/Cursor.h" #include "cru/platform/gui/sdl/Input.h" +#include "cru/platform/gui/sdl/InputMethod.h" #include "cru/platform/gui/sdl/UiApplication.h" #include <SDL3/SDL_events.h> @@ -25,6 +26,8 @@ SdlWindow::SdlWindow(SdlUiApplication* application) client_rect_(100, 100, 400, 200), parent_(nullptr) { application->RegisterWindow(this); + + input_context_ = std::make_unique<SdlInputMethodContext>(this); } SdlWindow::~SdlWindow() { application_->UnregisterWindow(this); } @@ -182,9 +185,13 @@ std::unique_ptr<graphics::IPainter> SdlWindow::BeginPaint() { NotImplemented(); } -IInputMethodContext* SdlWindow::GetInputMethodContext() { NotImplemented(); } +IInputMethodContext* SdlWindow::GetInputMethodContext() { + return input_context_.get(); +} + +SDL_Window* SdlWindow::GetSdlWindow() { return sdl_window_; } -std::optional<SDL_Window*> SdlWindow::GetSdlWindow() { return sdl_window_; } +SDL_WindowID SdlWindow::GetSdlWindowId() { return sdl_window_id_; } SdlUiApplication* SdlWindow::GetSdlUiApplication() { return application_; } @@ -280,9 +287,39 @@ NativeMouseButtonEventArgs ConvertMouseButtonEvent( NativeKeyEventArgs ConvertKeyEvent(const SDL_KeyboardEvent& event) { return {ConvertKeyScanCode(event.scancode), ConvertKeyModifier(event.mod)}; } + +std::optional<SDL_WindowID> GetEventWindowId(const SDL_Event& event) { + switch (event.type) { + case SDL_EVENT_WINDOW_MOVED: + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_SHOWN: + case SDL_EVENT_WINDOW_HIDDEN: + case SDL_EVENT_WINDOW_MINIMIZED: + case SDL_EVENT_WINDOW_FOCUS_GAINED: + case SDL_EVENT_WINDOW_FOCUS_LOST: + case SDL_EVENT_WINDOW_MOUSE_ENTER: + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + case SDL_EVENT_WINDOW_DESTROYED: + return event.window.windowID; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + return event.button.windowID; + case SDL_EVENT_MOUSE_WHEEL: + return event.wheel.windowID; + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + return event.key.windowID; + default: + return std::nullopt; + } +} } // namespace bool SdlWindow::HandleEvent(const SDL_Event* event) { + if (input_context_->HandleEvent(event)) return true; + + if (sdl_window_id_ != GetEventWindowId(*event)) return false; + switch (event->type) { case SDL_EVENT_WINDOW_MOVED: { client_rect_.left = event->window.data1; |
