mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-20 21:43:50 +00:00
Move the console input handler to CConsole
`conInputHandler` isn't global anymore. That makes the interface simpler and might make the compilation and the runtime faster.
This commit is contained in:
+55
-55
@@ -60,12 +60,15 @@
|
||||
#include <SDL_stdinc.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <concepts>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <iterator>
|
||||
#include <js/RootingAPI.h>
|
||||
#include <js/TypeDecls.h>
|
||||
#include <js/Value.h>
|
||||
#include <numeric>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -76,11 +79,44 @@ namespace
|
||||
// For text being typed into the console.
|
||||
constexpr int CONSOLE_BUFFER_SIZE = 1024;
|
||||
|
||||
template<std::invocable<std::string> Function>
|
||||
void ShowQuitHotkeys(bool& quitHotkeyWasShown, Function insertMessage)
|
||||
{
|
||||
if (std::exchange(quitHotkeyWasShown, true))
|
||||
return;
|
||||
|
||||
const std::string str{std::accumulate(g_HotkeyMap.begin(), g_HotkeyMap.end(), std::string{},
|
||||
[](std::string acc, const std::pair<const SDL_Scancode_, KeyMapping>& key)
|
||||
{
|
||||
if (std::get<1>(key).front().name != "console.toggle")
|
||||
return acc;
|
||||
|
||||
return acc + (acc.empty() ? "Press " : " / ") +
|
||||
FindScancodeName(static_cast<SDL_Scancode>(std::get<0>(key)));
|
||||
})};
|
||||
|
||||
if (!str.empty())
|
||||
insertMessage(str + " to quit.");
|
||||
}
|
||||
|
||||
template<std::invocable<std::string> Function>
|
||||
void SetVisible(const bool visible, bool& quitHotkeyWasShown, Function insertMessage)
|
||||
{
|
||||
// TODO: this should be based on input focus, not visibility
|
||||
if (visible)
|
||||
{
|
||||
ShowQuitHotkeys(quitHotkeyWasShown, std::move(insertMessage));
|
||||
SDL_StartTextInput();
|
||||
return;
|
||||
}
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
CConsole* g_Console = 0;
|
||||
|
||||
CConsole::CConsole()
|
||||
CConsole::CConsole() :
|
||||
m_InputHandler{g_VideoMode.m_InputManager, Input::Slot::CONSOLE, {*this}}
|
||||
{
|
||||
m_Toggle = false;
|
||||
m_Visible = false;
|
||||
@@ -139,37 +175,6 @@ void CConsole::UpdateScreenSize(int w, int h)
|
||||
m_Height = height / g_VideoMode.GetScale();
|
||||
}
|
||||
|
||||
void CConsole::ShowQuitHotkeys()
|
||||
{
|
||||
if (m_QuitHotkeyWasShown)
|
||||
return;
|
||||
|
||||
std::string str;
|
||||
for (const std::pair<const SDL_Scancode_, KeyMapping>& key : g_HotkeyMap)
|
||||
if (key.second.front().name == "console.toggle")
|
||||
str += (str.empty() ? "Press " : " / ") + FindScancodeName(static_cast<SDL_Scancode>(key.first));
|
||||
|
||||
if (!str.empty())
|
||||
InsertMessage(str + " to quit.");
|
||||
|
||||
m_QuitHotkeyWasShown = true;
|
||||
}
|
||||
|
||||
void CConsole::ToggleVisible()
|
||||
{
|
||||
m_Toggle = true;
|
||||
m_Visible = !m_Visible;
|
||||
|
||||
// TODO: this should be based on input focus, not visibility
|
||||
if (m_Visible)
|
||||
{
|
||||
ShowQuitHotkeys();
|
||||
SDL_StartTextInput();
|
||||
return;
|
||||
}
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
|
||||
void CConsole::SetVisible(bool visible)
|
||||
{
|
||||
if (visible != m_Visible)
|
||||
@@ -579,12 +584,6 @@ void CConsole::InsertMessage(const std::string& message)
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t* CConsole::GetBuffer()
|
||||
{
|
||||
m_Buffer[m_BufferLength] = 0;
|
||||
return m_Buffer.get();
|
||||
}
|
||||
|
||||
void CConsole::SetBuffer(const wchar_t* szMessage)
|
||||
{
|
||||
int oldBufferPos = m_BufferPos; // remember since FlushBuffer will set it to 0
|
||||
@@ -692,44 +691,45 @@ static bool isUnprintableChar(SDL_Keysym key)
|
||||
}
|
||||
}
|
||||
|
||||
Input::Reaction conInputHandler(const SDL_Event& ev)
|
||||
Input::Reaction CConsole::InputHandler::operator()(const SDL_Event& ev)
|
||||
{
|
||||
if (!g_Console)
|
||||
return Input::Reaction::PASS;
|
||||
|
||||
if (static_cast<int>(ev.type) == SDL_HOTKEYPRESS)
|
||||
{
|
||||
std::string hotkey = static_cast<const char*>(ev.user.data1);
|
||||
std::string_view hotkey{static_cast<const char*>(ev.user.data1)};
|
||||
|
||||
if (hotkey == "console.toggle")
|
||||
{
|
||||
ResetActiveHotkeys();
|
||||
g_Console->ToggleVisible();
|
||||
console.m_Toggle = true;
|
||||
console.m_Visible = !console.m_Visible;
|
||||
::SetVisible(console.m_Visible, console.m_QuitHotkeyWasShown, [&](auto&&... args){
|
||||
console.InsertMessage(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
return Input::Reaction::HANDLED;
|
||||
}
|
||||
else if (g_Console->IsActive() && hotkey == "copy")
|
||||
if (!console.IsActive())
|
||||
return Input::Reaction::PASS;
|
||||
if (hotkey == "copy")
|
||||
{
|
||||
std::string text = utf8_from_wstring(g_Console->GetBuffer());
|
||||
SDL_SetClipboardText(text.c_str());
|
||||
console.m_Buffer[console.m_BufferLength] = 0;
|
||||
SDL_SetClipboardText(utf8_from_wstring(console.m_Buffer.get()).c_str());
|
||||
return Input::Reaction::HANDLED;
|
||||
}
|
||||
else if (g_Console->IsActive() && hotkey == "paste")
|
||||
if (hotkey == "paste")
|
||||
{
|
||||
char* utf8_text = SDL_GetClipboardText();
|
||||
if (!utf8_text)
|
||||
return Input::Reaction::HANDLED;
|
||||
|
||||
std::wstring text = wstring_from_utf8(utf8_text);
|
||||
for (wchar_t c : wstring_from_utf8(utf8_text))
|
||||
console.InsertChar(0, c);
|
||||
SDL_free(utf8_text);
|
||||
|
||||
for (wchar_t c : text)
|
||||
g_Console->InsertChar(0, c);
|
||||
|
||||
return Input::Reaction::HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_Console->IsActive())
|
||||
if (!console.IsActive())
|
||||
return Input::Reaction::PASS;
|
||||
|
||||
// In SDL2, we no longer get Unicode wchars via SDL_Keysym
|
||||
@@ -739,7 +739,7 @@ Input::Reaction conInputHandler(const SDL_Event& ev)
|
||||
// TODO: this could be more efficient with an interface to insert UTF-8 strings directly
|
||||
std::wstring wstr = wstring_from_utf8(ev.text.text);
|
||||
for (size_t i = 0; i < wstr.length(); ++i)
|
||||
g_Console->InsertChar(0, wstr[i]);
|
||||
console.InsertChar(0, wstr[i]);
|
||||
return Input::Reaction::HANDLED;
|
||||
}
|
||||
// TODO: text editing events for IME support
|
||||
@@ -753,7 +753,7 @@ Input::Reaction conInputHandler(const SDL_Event& ev)
|
||||
if (ev.type == SDL_KEYDOWN && isUnprintableChar(ev.key.keysym) &&
|
||||
!HotkeyIsPressed("console.toggle"))
|
||||
{
|
||||
g_Console->InsertChar(sym, 0);
|
||||
console.InsertChar(sym, 0);
|
||||
return Input::Reaction::HANDLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
|
||||
void UpdateScreenSize(int w, int h);
|
||||
|
||||
void ToggleVisible();
|
||||
void SetVisible(bool visible);
|
||||
|
||||
/**
|
||||
@@ -64,14 +63,10 @@ public:
|
||||
|
||||
void Render(CCanvas2D& canvas);
|
||||
|
||||
void InsertChar(const int szChar, const wchar_t cooked);
|
||||
|
||||
void InsertMessage(const std::string& message);
|
||||
|
||||
void SetBuffer(const wchar_t* szMessage);
|
||||
|
||||
// Only returns a pointer to the buffer; copy out of here if you want to keep it.
|
||||
const wchar_t* GetBuffer();
|
||||
void FlushBuffer();
|
||||
|
||||
bool IsActive() const { return m_Visible; }
|
||||
@@ -115,6 +110,8 @@ private:
|
||||
bool m_QuitHotkeyWasShown; // show console.toggle hotkey values at first time
|
||||
double m_CursorBlinkRate; // cursor blink rate in seconds, if greater than 0.0
|
||||
|
||||
void InsertChar(const int szChar, const wchar_t cooked);
|
||||
|
||||
void DrawWindow(CCanvas2D& canvas);
|
||||
void DrawHistory(CTextRenderer& textRenderer);
|
||||
void DrawBuffer(CTextRenderer& textRenderer);
|
||||
@@ -131,11 +128,15 @@ private:
|
||||
|
||||
void LoadHistory();
|
||||
void SaveHistory();
|
||||
void ShowQuitHotkeys();
|
||||
|
||||
struct InputHandler
|
||||
{
|
||||
CConsole& console;
|
||||
Input::Reaction operator()(const SDL_Event& ev);
|
||||
};
|
||||
Input::Handler<InputHandler> m_InputHandler;
|
||||
};
|
||||
|
||||
extern CConsole* g_Console;
|
||||
|
||||
extern Input::Reaction conInputHandler(const SDL_Event& ev);
|
||||
|
||||
#endif // INCLUDED_CCONSOLE
|
||||
|
||||
@@ -268,8 +268,6 @@ static void InitPs(bool setup_gui, const CStrW& gui_page, ScriptInterface* srcSc
|
||||
// hotkey handler so that input boxes can be typed in without
|
||||
// setting off hotkeys.
|
||||
handlers->emplace(g_VideoMode.m_InputManager, Input::Slot::GUI, gui_handler);
|
||||
// Likewise for the console.
|
||||
handlers->emplace(g_VideoMode.m_InputManager, Input::Slot::CONSOLE, conInputHandler);
|
||||
|
||||
handlers->emplace(g_VideoMode.m_InputManager, Input::Slot::TOUCH_INPUT, touch_input_handler);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user