Rewritten text input to SDL2

dev-time-step
krzys-h 2015-09-25 19:49:50 +02:00
parent 7839dce624
commit e965414d34
6 changed files with 91 additions and 20 deletions

View File

@ -97,6 +97,7 @@ struct ApplicationPrivate
SDL_memset(&currentEvent, 0, sizeof(SDL_Event));
SDL_memset(&lastMouseMotionEvent, 0, sizeof(SDL_Event));
window = nullptr;
glcontext = nullptr;
joystick = nullptr;
joystickTimer = 0;
}
@ -1038,7 +1039,6 @@ Event CApplication::ProcessSystemEvent()
data->virt = false;
data->key = m_private->currentEvent.key.keysym.sym;
data->unicode = m_private->currentEvent.key.keysym.sym; // TODO: use SDL_TEXTINPUT for this, and remove this field
event.kmodState = m_private->currentEvent.key.keysym.mod;
// Some keyboards return numerical enter keycode instead of normal enter
@ -1055,6 +1055,13 @@ Event CApplication::ProcessSystemEvent()
event.data = std::move(data);
}
else if (m_private->currentEvent.type == SDL_TEXTINPUT)
{
event.type = EVENT_TEXT_INPUT;
auto data = MakeUnique<TextInputData>();
data->text = m_private->currentEvent.text.text;
event.data = std::move(data);
}
else if (m_private->currentEvent.type == SDL_MOUSEWHEEL)
{
event.type = EVENT_MOUSE_WHEEL;
@ -1127,11 +1134,17 @@ void CApplication::LogEvent(const Event &event)
};
// Print the events in debug mode to test the code
if (IsDebugModeActive(DEBUG_SYS_EVENTS) || IsDebugModeActive(DEBUG_APP_EVENTS))
if (IsDebugModeActive(DEBUG_SYS_EVENTS) || IsDebugModeActive(DEBUG_UPDATE_EVENTS) || IsDebugModeActive(DEBUG_APP_EVENTS))
{
std::string eventType = ParseEventType(event.type);
if (IsDebugModeActive(DEBUG_SYS_EVENTS) && event.type <= EVENT_SYS_MAX)
if (IsDebugModeActive(DEBUG_UPDATE_EVENTS) && event.type == EVENT_FRAME)
{
l->Trace("Update event: %s\n", eventType.c_str());
PrintEventDetails();
}
if (IsDebugModeActive(DEBUG_SYS_EVENTS) && (event.type <= EVENT_SYS_MAX && event.type != EVENT_FRAME))
{
l->Trace("System event %s:\n", eventType.c_str());
switch (event.type)
@ -1142,7 +1155,12 @@ void CApplication::LogEvent(const Event &event)
auto data = event.GetData<KeyEventData>();
l->Trace(" virt = %s\n", data->virt ? "true" : "false");
l->Trace(" key = %d\n", data->key);
l->Trace(" unicode = 0x%04x\n", data->unicode);
break;
}
case EVENT_TEXT_INPUT:
{
auto data = event.GetData<TextInputData>();
l->Trace(" text = %s\n", data->text.c_str());
break;
}
case EVENT_MOUSE_BUTTON_DOWN:
@ -1231,7 +1249,6 @@ Event CApplication::CreateVirtualEvent(const Event& sourceEvent)
auto data = MakeUnique<KeyEventData>();
data->virt = true;
data->key = VIRTUAL_JOY(sourceData->button);
data->unicode = 0;
virtualEvent.data = std::move(data);
}
else
@ -1431,6 +1448,10 @@ bool CApplication::ParseDebugModes(const std::string& str, int& debugModes)
{
debugModes |= DEBUG_SYS_EVENTS;
}
else if (modeToken == "update_events")
{
debugModes |= DEBUG_UPDATE_EVENTS;
}
else if (modeToken == "app_events")
{
debugModes |= DEBUG_APP_EVENTS;
@ -1758,3 +1779,15 @@ bool CApplication::GetSceneTestMode()
{
return m_sceneTest;
}
void CApplication::SetTextInput(bool textInputEnabled)
{
if (textInputEnabled)
{
SDL_StartTextInput();
}
else
{
SDL_StopTextInput();
}
}

View File

@ -125,9 +125,10 @@ enum PerformanceCounter
enum DebugMode
{
DEBUG_SYS_EVENTS = 1 << 0,
DEBUG_APP_EVENTS = 1 << 1,
DEBUG_EVENTS = DEBUG_SYS_EVENTS | DEBUG_APP_EVENTS,
DEBUG_MODELS = 1 << 2,
DEBUG_UPDATE_EVENTS = 1 << 1,
DEBUG_APP_EVENTS = 1 << 2,
DEBUG_EVENTS = DEBUG_SYS_EVENTS | DEBUG_UPDATE_EVENTS | DEBUG_APP_EVENTS,
DEBUG_MODELS = 1 << 3,
DEBUG_ALL = DEBUG_SYS_EVENTS | DEBUG_APP_EVENTS | DEBUG_MODELS
};
@ -270,6 +271,10 @@ public:
MouseMode GetMouseMode() const;
//@}
//! Enable/disable text input, this toggles the on-screen keyboard on some platforms
/** This also allows for writing in CJK languages (not tested!), see https://wiki.libsdl.org/Tutorials/TextInput for detailed explanation */
void SetTextInput(bool textInputEnabled);
//! Moves (warps) the mouse cursor to the specified position (in interface coords)
void MoveMouse(Math::Point pos);

View File

@ -57,6 +57,8 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_ACTIVE] = "EVENT_ACTIVE";
EVENT_TYPE_TEXT[EVENT_TEXT_INPUT] = "EVENT_TEXT_INPUT";
EVENT_TYPE_TEXT[EVENT_JOY_AXIS] = "EVENT_JOY_AXIS";
EVENT_TYPE_TEXT[EVENT_JOY_BUTTON_DOWN] = "EVENT_JOY_BUTTON_DOWN";
EVENT_TYPE_TEXT[EVENT_JOY_BUTTON_UP] = "EVENT_JOY_BUTTON_UP";

View File

@ -70,6 +70,9 @@ enum EventType
//! Event sent when application window loses/gains focus
EVENT_ACTIVE = 10,
//! Event sent when user inputs some character
EVENT_TEXT_INPUT = 11,
//! Event sent after moving joystick axes
EVENT_JOY_AXIS = 12,
//! Event sent after pressing a joystick button
@ -569,13 +572,25 @@ struct KeyEventData : public EventData
bool virt = false;
//! Key symbol: KEY(...) macro value or virtual key VIRTUAL_... (from common/key.h)
unsigned int key = 0;
//! Unicode character
//! NOTE: applicable only to EVENT_KEY_DOWN events!
unsigned int unicode = 0;
//! Input binding slot for this key
InputSlot slot = INPUT_SLOT_LEFT;
InputSlot slot = INPUT_SLOT_MAX;
};
/**
* \struct TextInputData
* \brief Additional data for text input event
*/
struct TextInputData : public EventData
{
std::unique_ptr<EventData> Clone() const override
{
return MakeUnique<TextInputData>(*this);
}
//! Text entered by the user (usually one character, UTF-8 encoded)
std::string text = "";
};
/**
* \enum MouseButton
* \brief Mouse button

View File

@ -143,6 +143,11 @@ CEdit::CEdit()
CEdit::~CEdit()
{
FreeImage();
if (m_bFocus)
{
CApplication::GetInstancePointer()->SetTextInput(false);
}
}
@ -473,15 +478,12 @@ bool CEdit::EventProcess(const Event &event)
}
}
if ( event.type == EVENT_KEY_DOWN && !bControl && m_bFocus )
if ( event.type == EVENT_TEXT_INPUT && !bControl && m_bFocus )
{
auto data = event.GetData<KeyEventData>();
if (data->unicode >= ' ')
{
Insert(static_cast<char>(data->unicode)); // TODO: insert utf-8 char
SendModifEvent();
return true;
}
auto data = event.GetData<TextInputData>();
Insert(data->text[0]); // TODO: insert utf-8 char
SendModifEvent();
return true;
}
if ( event.type == EVENT_FOCUS )
@ -3215,4 +3217,16 @@ void CEdit::UpdateScroll()
}
}
void CEdit::SetFocus(CControl* control)
{
bool oldFocus = m_bFocus;
CControl::SetFocus(control);
if (oldFocus != m_bFocus)
{
// Start/stop text input mode, this toggles the on-screen keyboard
CApplication::GetInstancePointer()->SetTextInput(m_bFocus);
}
}
}

View File

@ -227,6 +227,8 @@ protected:
void UpdateScroll();
void SetFocus(CControl* control) override;
protected:
std::unique_ptr<CScroll> m_scroll; // vertical scrollbar on the right