From 5b22e2f1802af3a2bc270092e32fbad8bc90bba0 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sat, 27 Jul 2024 08:55:05 +0200 Subject: [PATCH] Implement ShowFloatingGamepadTextInput API and FloatingGamepadTextInputDismissed event. (#329) Fixes #327 --- binding.gyp | 1 + docs/events.md | 8 +++++- docs/utils.md | 21 +++++++++++++++ src/api/steam_api_utils.cc | 55 ++++++++++++++++++++++++++++++++++++++ src/steam_client.cc | 21 ++++++++++----- src/steam_client.h | 14 +++++++--- src/steam_event.cc | 9 +++++++ src/steam_event.h | 1 + 8 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 src/api/steam_api_utils.cc diff --git a/binding.gyp b/binding.gyp index 3dcf6eda..37aaf090 100644 --- a/binding.gyp +++ b/binding.gyp @@ -78,6 +78,7 @@ 'src/api/steam_api_registry.h', 'src/api/steam_api_settings.cc', 'src/api/steam_api_stats.cc', + 'src/api/steam_api_utils.cc', 'src/api/steam_api_workshop.cc', 'src/greenworks_api.cc', 'src/greenworks_async_workers.cc', diff --git a/docs/events.md b/docs/events.md index 9db3f2a2..5c1cf41e 100644 --- a/docs/events.md +++ b/docs/events.md @@ -150,4 +150,10 @@ Returns: Posted after the user executes a steam url with command line or query parameters such as `steam://run///?param1=value1;param2=value2;param3=value3;` while the game is already running. The new params can be queried with [GetLaunchCommandLine](https://partner.steamgames.com/doc/api/ISteamApps#GetLaunchCommandLine) and [GetLaunchQueryParam](https://partner.steamgames.com/doc/api/ISteamApps#GetLaunchQueryParam). -[Steam docs](https://partner.steamgames.com/doc/api/ISteamApps#NewUrlLaunchParameters_t) \ No newline at end of file +[Steam docs](https://partner.steamgames.com/doc/api/ISteamApps#NewUrlLaunchParameters_t) + +### Event: 'floating-gamepad-text-input-dismissed' + +Emitted when the floating keyboard invoked from ShowFloatingGamepadTextInput has been closed. + +[Steam docs](https://partner.steamgames.com/doc/api/ISteamUtils#FloatingGamepadTextInputDismissed_t) diff --git a/docs/utils.md b/docs/utils.md index 331ac3a2..0a56c6f8 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -1,5 +1,26 @@ ## Methods +### greenworks.FloatingGamepadTextInputMode + +Represents Steam SDK `EFloatingGamepadTextInputMode`. + +* `SingleLine` +* `MultipleLines` +* `Email` +* `Numeric` + +### greenworks.showFloatingGamepadTextInput(keyboardMode, x, y, width, height) + +* `keyboardMode` greenworks.FloatingGamepadTextInputMode +* `x` Integer +* `y` Integer +* `width` Integer +* `height` Integer + +Opens a floating keyboard over the game content and sends OS keyboard keys directly to the game. + +Returns `true` if the floating keyboard was shown, otherwise `false`. + ### greenworks.Utils.move(source_dir, target_dir, [success_callback], [error_callback]) * `source_dir` String diff --git a/src/api/steam_api_utils.cc b/src/api/steam_api_utils.cc new file mode 100644 index 00000000..9d98a991 --- /dev/null +++ b/src/api/steam_api_utils.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2024 Greenheart Games Pty. Ltd. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "nan.h" +#include "v8.h" + +#include "steam/steam_api.h" + +#include "steam_api_registry.h" + +namespace greenworks { +namespace api { +namespace { + +void InitFloatingGamepadTextInputMode(v8::Local exports) { + v8::Local mode = Nan::New(); + SET_TYPE(mode, "SingleLine", k_EFloatingGamepadTextInputModeModeSingleLine); + SET_TYPE(mode, "MultipleLines", k_EFloatingGamepadTextInputModeModeMultipleLines); + SET_TYPE(mode, "Email", + k_EFloatingGamepadTextInputModeModeEmail); + SET_TYPE(mode, "Numeric", k_EFloatingGamepadTextInputModeModeNumeric); + Nan::Persistent constructor; + constructor.Reset(mode); + Nan::Set(exports, + Nan::New("FloatingGamepadTextInputMode").ToLocalChecked(), + mode); +} + +NAN_METHOD(ShowFloatingGamepadTextInput) { + Nan::HandleScope scope; + if (info.Length() < 5 || !info[0]->IsInt32() || !info[1]->IsInt32() || + !info[2]->IsInt32() || !info[3]->IsInt32() || !info[4]->IsString()) { + THROW_BAD_ARGS("Bad arguments"); + } + + EFloatingGamepadTextInputMode input_mode = + static_cast( + Nan::To(info[0]).FromJust()); + info.GetReturnValue().Set(SteamUtils()->ShowFloatingGamepadTextInput( + input_mode, Nan::To(info[1]).FromJust(), + Nan::To(info[2]).FromJust(), Nan::To(info[3]).FromJust(), + Nan::To(info[4]).FromJust())); +} + +void RegisterAPIs(v8::Local target) { + InitFloatingGamepadTextInputMode(target); + SET_FUNCTION("showFloatingGamepadTextInput", ShowFloatingGamepadTextInput); +} + +SteamAPIRegistry::Add X(RegisterAPIs); + +} // namespace +} // namespace api +} // namespace greenworks diff --git a/src/steam_client.cc b/src/steam_client.cc index 9f2f2442..c2fc1a26 100644 --- a/src/steam_client.cc +++ b/src/steam_client.cc @@ -7,6 +7,7 @@ #include #include "nan.h" +#include "steam/isteamutils.h" namespace greenworks { @@ -41,19 +42,20 @@ SteamClient::SteamClient() steam_persona_state_change_(this, &SteamClient::OnPeronaStateChange), avatar_image_loaded_(this, &SteamClient::OnAvatarImageLoaded), game_connected_friend_chat_msg_( - this, - &SteamClient::OnGameConnectedFriendChatMessage), + this, &SteamClient::OnGameConnectedFriendChatMessage), dlc_installed_(this, &SteamClient::OnDLCInstalled), MicroTxnAuthorizationResponse_( - this, - &SteamClient::OnMicroTxnAuthorizationResponse), + this, &SteamClient::OnMicroTxnAuthorizationResponse), OnLobbyCreated_(this, &SteamClient::OnLobbyCreated), OnLobbyDataUpdate_(this, &SteamClient::OnLobbyDataUpdate), OnLobbyEnter_(this, &SteamClient::OnLobbyEnter), OnLobbyInvite_(this, &SteamClient::OnLobbyInvite), OnGameLobbyJoinRequested_(this, &SteamClient::OnGameLobbyJoinRequested), - OnGameRichPresenceJoinRequested_(this, &SteamClient::OnGameRichPresenceJoinRequested), - OnNewUrlLaunchParameters_(this, &SteamClient::OnNewUrlLaunchParameters) {} + OnGameRichPresenceJoinRequested_( + this, &SteamClient::OnGameRichPresenceJoinRequested), + OnNewUrlLaunchParameters_(this, &SteamClient::OnNewUrlLaunchParameters), + OnFloatingGamepadTextInputDismissed_( + this, &SteamClient::OnFloatingGamepadTextInputDismissed) {} SteamClient::~SteamClient() { for (size_t i = 0; i < observer_list_.size(); ++i) { @@ -204,6 +206,13 @@ void SteamClient::OnNewUrlLaunchParameters(NewUrlLaunchParameters_t *callback) { } } +void SteamClient::OnFloatingGamepadTextInputDismissed( + FloatingGamepadTextInputDismissed_t *callback) { + for (size_t i = 0; i < observer_list_.size(); ++i) { + observer_list_[i]->OnFloatingGamepadTextInputDismissed(); + } +} + void SteamClient::StartSteamLoop() { if (g_steam_timer) return; diff --git a/src/steam_client.h b/src/steam_client.h index feccad96..ea00a9d8 100644 --- a/src/steam_client.h +++ b/src/steam_client.h @@ -42,6 +42,7 @@ class SteamClient { virtual void OnGameLobbyJoinRequested(uint64 SteamIdLobby, uint64 SteamIdUser) = 0; virtual void OnGameRichPresenceJoinRequested(uint64 steamIDFriend, std::string rgchConnect) = 0; virtual void OnNewUrlLaunchParameters() = 0; + virtual void OnFloatingGamepadTextInputDismissed() = 0; virtual ~Observer() {} }; @@ -90,9 +91,16 @@ class SteamClient { STEAM_CALLBACK(SteamClient, OnLobbyDataUpdate, LobbyDataUpdate_t, OnLobbyDataUpdate_); STEAM_CALLBACK(SteamClient, OnLobbyEnter, LobbyEnter_t, OnLobbyEnter_); STEAM_CALLBACK(SteamClient, OnLobbyInvite, LobbyInvite_t, OnLobbyInvite_); - STEAM_CALLBACK(SteamClient, OnGameLobbyJoinRequested, GameLobbyJoinRequested_t, OnGameLobbyJoinRequested_); - STEAM_CALLBACK(SteamClient, OnGameRichPresenceJoinRequested, GameRichPresenceJoinRequested_t, OnGameRichPresenceJoinRequested_); - STEAM_CALLBACK(SteamClient, OnNewUrlLaunchParameters, NewUrlLaunchParameters_t, OnNewUrlLaunchParameters_); + STEAM_CALLBACK(SteamClient, OnGameLobbyJoinRequested, + GameLobbyJoinRequested_t, OnGameLobbyJoinRequested_); + STEAM_CALLBACK(SteamClient, OnGameRichPresenceJoinRequested, + GameRichPresenceJoinRequested_t, + OnGameRichPresenceJoinRequested_); + STEAM_CALLBACK(SteamClient, OnNewUrlLaunchParameters, + NewUrlLaunchParameters_t, OnNewUrlLaunchParameters_); + STEAM_CALLBACK(SteamClient, OnFloatingGamepadTextInputDismissed, + FloatingGamepadTextInputDismissed_t, + OnFloatingGamepadTextInputDismissed_); }; } // namespace greenworks diff --git a/src/steam_event.cc b/src/steam_event.cc index 153ac0a4..71de3016 100644 --- a/src/steam_event.cc +++ b/src/steam_event.cc @@ -212,4 +212,13 @@ void SteamEvent::OnNewUrlLaunchParameters() { Nan::New(persistent_steam_events_), "on", 1, argv); } +void SteamEvent::OnFloatingGamepadTextInputDismissed() { + Nan::HandleScope scope; + v8::Local argv[] = { + Nan::New("floating-gamepad-text-input-dismissed").ToLocalChecked()}; + Nan::AsyncResource ar( + "greenworks:SteamEvent.OnFloatingGamepadTextInputDismissed"); + ar.runInAsyncScope(Nan::New(persistent_steam_events_), "on", 1, argv); +} + } // namespace greenworks diff --git a/src/steam_event.h b/src/steam_event.h index f06afccd..6e9b20a1 100644 --- a/src/steam_event.h +++ b/src/steam_event.h @@ -45,6 +45,7 @@ class SteamEvent : public greenworks::SteamClient::Observer { void OnGameRichPresenceJoinRequested(uint64 steamIDFriend, std::string rgchConnect) override; void OnNewUrlLaunchParameters() override; + void OnFloatingGamepadTextInputDismissed() override; private: const Nan::Persistent& persistent_steam_events_;