mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 13:44:58 +00:00
feat: Add mouse grab state change event and related handling in input services
This commit is contained in:
@@ -32,6 +32,7 @@ enum class EventType {
|
||||
MouseButtonPressed,
|
||||
MouseButtonReleased,
|
||||
MouseWheel,
|
||||
MouseGrabChanged,
|
||||
TextInput,
|
||||
|
||||
// Rendering events
|
||||
@@ -147,6 +148,13 @@ struct MouseWheelEvent {
|
||||
bool flipped;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Mouse grab state change event data.
|
||||
*/
|
||||
struct MouseGrabEvent {
|
||||
bool grabbed;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Text input event data.
|
||||
*/
|
||||
|
||||
@@ -66,10 +66,31 @@ SdlInputService::SdlInputService(std::shared_ptr<events::IEventBus> eventBus,
|
||||
OnTextInput(e);
|
||||
});
|
||||
|
||||
eventBus_->Subscribe(events::EventType::WindowFocusGained, [this](const events::Event& e) {
|
||||
OnWindowFocusGained(e);
|
||||
});
|
||||
|
||||
eventBus_->Subscribe(events::EventType::WindowFocusLost, [this](const events::Event& e) {
|
||||
OnWindowFocusLost(e);
|
||||
});
|
||||
|
||||
eventBus_->Subscribe(events::EventType::MouseGrabChanged, [this](const events::Event& e) {
|
||||
OnMouseGrabChanged(e);
|
||||
});
|
||||
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlInputService", "SdlInputService",
|
||||
"eventBus=" + std::string(eventBus_ ? "set" : "null"));
|
||||
}
|
||||
if (configService_) {
|
||||
const auto& mouseGrabConfig = configService_->GetMouseGrabConfig();
|
||||
mouseGrabGatesLook_ = mouseGrabConfig.enabled &&
|
||||
(mouseGrabConfig.grabOnClick || mouseGrabConfig.startGrabbed);
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlInputService", "SdlInputService",
|
||||
"mouseGrabGatesLook=" + std::string(mouseGrabGatesLook_ ? "true" : "false"));
|
||||
}
|
||||
}
|
||||
BuildActionKeyMapping();
|
||||
EnsureGamepadSubsystem();
|
||||
}
|
||||
@@ -102,8 +123,10 @@ void SdlInputService::ProcessEvent(const SDL_Event& event) {
|
||||
// GUI input processing
|
||||
guiInputSnapshot_.mouseX = static_cast<float>(event.motion.x);
|
||||
guiInputSnapshot_.mouseY = static_cast<float>(event.motion.y);
|
||||
guiInputSnapshot_.mouseDeltaX += static_cast<float>(event.motion.xrel);
|
||||
guiInputSnapshot_.mouseDeltaY += static_cast<float>(event.motion.yrel);
|
||||
if (ShouldCaptureMouseDelta()) {
|
||||
guiInputSnapshot_.mouseDeltaX += static_cast<float>(event.motion.xrel);
|
||||
guiInputSnapshot_.mouseDeltaY += static_cast<float>(event.motion.yrel);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
@@ -218,8 +241,10 @@ void SdlInputService::OnMouseMoved(const events::Event& event) {
|
||||
state_.mouseY = mouseEvent.y;
|
||||
guiInputSnapshot_.mouseX = mouseEvent.x;
|
||||
guiInputSnapshot_.mouseY = mouseEvent.y;
|
||||
guiInputSnapshot_.mouseDeltaX += mouseEvent.deltaX;
|
||||
guiInputSnapshot_.mouseDeltaY += mouseEvent.deltaY;
|
||||
if (ShouldCaptureMouseDelta()) {
|
||||
guiInputSnapshot_.mouseDeltaX += mouseEvent.deltaX;
|
||||
guiInputSnapshot_.mouseDeltaY += mouseEvent.deltaY;
|
||||
}
|
||||
}
|
||||
|
||||
void SdlInputService::OnMouseButtonPressed(const events::Event& event) {
|
||||
@@ -275,6 +300,37 @@ void SdlInputService::OnTextInput(const events::Event& event) {
|
||||
guiInputSnapshot_.textInput += textEvent.text;
|
||||
}
|
||||
|
||||
void SdlInputService::OnWindowFocusGained(const events::Event& event) {
|
||||
(void)event;
|
||||
windowFocused_ = true;
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlInputService", "OnWindowFocusGained", "windowFocused=true");
|
||||
}
|
||||
}
|
||||
|
||||
void SdlInputService::OnWindowFocusLost(const events::Event& event) {
|
||||
(void)event;
|
||||
windowFocused_ = false;
|
||||
guiInputSnapshot_.mouseDeltaX = 0.0f;
|
||||
guiInputSnapshot_.mouseDeltaY = 0.0f;
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlInputService", "OnWindowFocusLost", "windowFocused=false");
|
||||
}
|
||||
}
|
||||
|
||||
void SdlInputService::OnMouseGrabChanged(const events::Event& event) {
|
||||
const auto& grabEvent = event.GetData<events::MouseGrabEvent>();
|
||||
mouseGrabbed_ = grabEvent.grabbed;
|
||||
if (!mouseGrabbed_) {
|
||||
guiInputSnapshot_.mouseDeltaX = 0.0f;
|
||||
guiInputSnapshot_.mouseDeltaY = 0.0f;
|
||||
}
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlInputService", "OnMouseGrabChanged",
|
||||
"grabbed=" + std::string(mouseGrabbed_ ? "true" : "false"));
|
||||
}
|
||||
}
|
||||
|
||||
void SdlInputService::BuildActionKeyMapping() {
|
||||
actionKeyNames_.clear();
|
||||
gamepadButtonActions_.clear();
|
||||
@@ -462,6 +518,16 @@ bool SdlInputService::IsActionKeyPressed(const std::string& action) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SdlInputService::ShouldCaptureMouseDelta() const {
|
||||
if (!windowFocused_) {
|
||||
return false;
|
||||
}
|
||||
if (mouseGrabGatesLook_) {
|
||||
return mouseGrabbed_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SdlInputService::EnsureGamepadSubsystem() {
|
||||
uint32_t initialized = SDL_WasInit(0);
|
||||
if ((initialized & SDL_INIT_GAMEPAD) != 0) {
|
||||
|
||||
@@ -53,6 +53,9 @@ private:
|
||||
GuiInputSnapshot guiInputSnapshot_;
|
||||
IGuiScriptService* guiScriptService_ = nullptr;
|
||||
SDL_Gamepad* gamepad_ = nullptr;
|
||||
bool windowFocused_ = true;
|
||||
bool mouseGrabbed_ = false;
|
||||
bool mouseGrabGatesLook_ = false;
|
||||
SDL_GamepadButton musicToggleButton_ = SDL_GAMEPAD_BUTTON_START;
|
||||
SDL_GamepadButton dpadUpButton_ = SDL_GAMEPAD_BUTTON_DPAD_UP;
|
||||
SDL_GamepadButton dpadDownButton_ = SDL_GAMEPAD_BUTTON_DPAD_DOWN;
|
||||
@@ -75,6 +78,9 @@ private:
|
||||
void OnMouseButtonReleased(const events::Event& event);
|
||||
void OnMouseWheel(const events::Event& event);
|
||||
void OnTextInput(const events::Event& event);
|
||||
void OnWindowFocusGained(const events::Event& event);
|
||||
void OnWindowFocusLost(const events::Event& event);
|
||||
void OnMouseGrabChanged(const events::Event& event);
|
||||
void EnsureGamepadSubsystem();
|
||||
void TryOpenGamepad();
|
||||
void CloseGamepad();
|
||||
@@ -82,6 +88,7 @@ private:
|
||||
void BuildActionKeyMapping();
|
||||
void ApplyKeyMapping(SDL_Keycode key, bool isDown);
|
||||
bool IsActionKeyPressed(const std::string& action) const;
|
||||
bool ShouldCaptureMouseDelta() const;
|
||||
|
||||
// GUI key mapping (extracted from old Sdl3App)
|
||||
static const std::unordered_map<SDL_Keycode, std::string> kGuiKeyNames;
|
||||
|
||||
@@ -378,6 +378,17 @@ void SdlWindowService::ApplyMouseGrab(bool grabbed) {
|
||||
|
||||
if (success) {
|
||||
mouseGrabbed_ = grabbed;
|
||||
if (eventBus_) {
|
||||
eventBus_->Publish(events::Event{
|
||||
events::EventType::MouseGrabChanged,
|
||||
GetCurrentTime(),
|
||||
events::MouseGrabEvent{grabbed}
|
||||
});
|
||||
}
|
||||
if (logger_) {
|
||||
logger_->Trace("SdlWindowService", "ApplyMouseGrab",
|
||||
"mouseGrabChanged=true, grabbed=" + std::string(grabbed ? "true" : "false"));
|
||||
}
|
||||
} else if (logger_) {
|
||||
logger_->Trace("SdlWindowService", "ApplyMouseGrab", "grabChangeFailed=true");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user