SparrowInput/src/input.cpp

342 lines
10 KiB
C++

/**
* @author: Thomas Brandého
*/
#include "input.h"
#include "imgui/imgui.h"
#include <iostream>
#include <SFML/Window.hpp>
#include <list>
Input::Input(sf::Window *w) :
m_window(w),
m_closeRequested(false),
m_mouseGrabbed(false),
m_mouseWasGrabbed(false)
{
m_heldKeys = std::vector<int>();
m_heldMouseButtons = std::vector<int>();
m_actions = std::vector<Action>();
m_window->setKeyRepeatEnabled(false);
ImGuiIO& io = ImGui::GetIO();
// init keyboard mapping
io.KeyMap[ImGuiKey_Tab] = sf::Keyboard::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = sf::Keyboard::Left;
io.KeyMap[ImGuiKey_RightArrow] = sf::Keyboard::Right;
io.KeyMap[ImGuiKey_UpArrow] = sf::Keyboard::Up;
io.KeyMap[ImGuiKey_DownArrow] = sf::Keyboard::Down;
io.KeyMap[ImGuiKey_PageUp] = sf::Keyboard::PageUp;
io.KeyMap[ImGuiKey_PageDown] = sf::Keyboard::PageDown;
io.KeyMap[ImGuiKey_Home] = sf::Keyboard::Home;
io.KeyMap[ImGuiKey_End] = sf::Keyboard::End;
io.KeyMap[ImGuiKey_Delete] = sf::Keyboard::Delete;
io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::BackSpace;
io.KeyMap[ImGuiKey_Enter] = sf::Keyboard::Return;
io.KeyMap[ImGuiKey_Escape] = sf::Keyboard::Escape;
io.KeyMap[ImGuiKey_A] = sf::Keyboard::A;
io.KeyMap[ImGuiKey_C] = sf::Keyboard::C;
io.KeyMap[ImGuiKey_V] = sf::Keyboard::V;
io.KeyMap[ImGuiKey_X] = sf::Keyboard::X;
io.KeyMap[ImGuiKey_Y] = sf::Keyboard::Y;
io.KeyMap[ImGuiKey_Z] = sf::Keyboard::Z;
}
void Input::setKeysMap(IKeysMap km){
m_keysmap = km;
}
void Input::updateEvents(){
sf::Event event;
ImGuiIO& io = ImGui::GetIO();
KeyBindings kb;
char c;
/* reset variables */
m_closeRequested = false;
m_hasBeenResized = false;
m_delta_vertical_scroll = 0;
m_buffer.clear();
if(m_mouseGrabbed)
m_last_mouse_position = sf::Vector2i(m_window->getSize())/2;
else
m_last_mouse_position = m_mouse_position;
/* global affectation */
kb = m_keybindings[m_current_context];
m_actions.clear();
Action action;
bool focus_on_imgui = ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow);
if(focus_on_imgui)
std::cout << "focused" << std::endl;
/* event-parsing loop */
while(m_window->pollEvent(event))
{
switch(event.type){
case sf::Event::Closed:
m_closeRequested = true;
break;
case sf::Event::Resized:
m_hasBeenResized = true;
break;
case sf::Event::LostFocus:
m_mouseWasGrabbed = m_mouseGrabbed;
m_mouseGrabbed = false;
break;
case sf::Event::GainedFocus:
m_mouseGrabbed = m_mouseWasGrabbed;
break;
case sf::Event::TextEntered:
if (focus_on_imgui)
io.AddInputCharacter(static_cast<ImWchar>(event.text.unicode));
else
sf::Utf32::encodeAnsi(event.text.unicode,std::back_inserter(m_buffer));
break;
case sf::Event::KeyPressed:
if(focus_on_imgui)
{
io.KeysDown[event.key.code] = true;
io.KeyCtrl = event.key.control;
io.KeyShift = event.key.shift;
io.KeyAlt = event.key.alt;
}
else
{
action = kb.getPressedAction(input::KEYBOARD,event.key.code);
if(!action.isNull())
m_actions.push_back(action);
m_heldKeys.push_back(event.key.code);
}
break;
case sf::Event::KeyReleased:
if (focus_on_imgui)
{
io.KeysDown[event.key.code] = false;
io.KeyCtrl = event.key.control;
io.KeyShift = event.key.shift;
io.KeyAlt = event.key.alt;
}
else
{
action = kb.getReleasedAction(input::KEYBOARD,event.key.code);
if(!action.isNull())
m_actions.push_back(action);
releaseHeldKeys(event.key.code);
}
break;
case sf::Event::MouseWheelScrolled:
if (!focus_on_imgui)
{
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
m_delta_vertical_scroll = event.mouseWheelScroll.delta;
}
break;
case sf::Event::MouseWheelMoved:
if (focus_on_imgui)
io.MouseWheel += static_cast<float>(event.mouseWheel.delta);
break;
case sf::Event::MouseButtonPressed:
if (!focus_on_imgui)
{
action = kb.getPressedAction(input::MOUSE,event.mouseButton.button);
if(!action.isNull())
m_actions.push_back(action);
m_heldMouseButtons.push_back(event.mouseButton.button);
}
break;
case sf::Event::MouseButtonReleased:
if(!focus_on_imgui)
{
action = kb.getReleasedAction(input::MOUSE,event.mouseButton.button);
if(!action.isNull())
m_actions.push_back(action);
releaseHeldMouseButton(event.mouseButton.button);
}
break;
case sf::Event::MouseMoved:
m_mouse_position = sf::Mouse::getPosition(*m_window);
if (focus_on_imgui)
{
io.MousePos = ImVec2(m_mouse_position.x, m_mouse_position.y);
}
break;
case sf::Event::MouseEntered:
// action MouseEntered
break;
case sf::Event::MouseLeft:
if(m_mouseGrabbed)
sf::Mouse::setPosition(m_last_mouse_position,*m_window);
break;
case sf::Event::JoystickButtonPressed:
action = kb.getPressedAction(input::CONTROLLER,event.joystickButton.button);
if(!action.isNull()){
action.controller_id = event.joystickButton.joystickId;
m_actions.push_back(action);
}
m_heldJoystickButtons[action.controller_id].push_back(event.joystickButton.button);
break;
case sf::Event::JoystickButtonReleased:
action = kb.getReleasedAction(input::CONTROLLER, event.joystickButton.button);
if(!action.isNull()){
action.controller_id = event.joystickButton.joystickId;
m_actions.push_back(action);
}
releaseHeldJoystickButton(event.joystickButton.button,action.controller_id);
break;
case sf::Event::JoystickMoved:
break;
case sf::Event::JoystickConnected:
m_heldJoystickButtons[event.joystickConnect.joystickId] = std::vector<int>();
break;
case sf::Event::JoystickDisconnected:
m_heldJoystickButtons.erase(event.joystickConnect.joystickId);
break;
}
}
if(m_mouseGrabbed)
sf::Mouse::setPosition(m_last_mouse_position, *m_window);
for (auto key: m_heldKeys)
m_actions.push_back(kb.getHoldAction(input::KEYBOARD,key));
for (int i = 0; i < 3; i++)
io.MouseDown[i] = false;
for (int button: m_heldMouseButtons)
{
m_actions.push_back(kb.getHoldAction(input::MOUSE, button));
io.MouseDown[button] = true;
}
for (auto heldJoystickButton : m_heldJoystickButtons)
{
for (auto button: heldJoystickButton.second)
{
action = kb.getHoldAction(input::CONTROLLER,button);
action.controller_id = heldJoystickButton.first;
m_actions.push_back(action);
}
}
}
std::vector<Action> Input::getActions()
{
return m_actions;
}
/* context-related functions */
std::vector<std::string> Input::getContextsList()
{
std::vector<std::string> res;
for(auto context : m_contexts)
res.push_back(context.getName());
return res;
}
void Input::updateKeyBindings()
{
m_keybindings.clear();
for (auto iter= m_contexts.begin(); iter != m_contexts.end(); ++iter)
m_keybindings[iter->getName()]= KeyBindings(*iter,m_keysmap);
}
/* window-related function */
bool Input::isCloseRequested() const
{
return m_closeRequested;
}
bool Input::isResized() const
{
return m_hasBeenResized;
}
/* keyboard-related functions */
bool Input::isKeyPressed(int key) const
{
return sf::Keyboard::isKeyPressed((sf::Keyboard::Key) key);
}
void Input::releaseHeldKeys(int keycode)
{
for(auto iter = m_heldKeys.begin();iter < m_heldKeys.end();)
iter = *iter == keycode ? m_heldKeys.erase(iter) : iter+1;
}
void Input::releaseHeldMouseButton(int buttoncode)
{
for(auto iter = m_heldMouseButtons.begin();iter<m_heldMouseButtons.end();)
iter = *iter == buttoncode ? m_heldMouseButtons.erase(iter) : iter+1;
}
void Input::releaseHeldJoystickButton(int buttoncode,int controller_id)
{
for(auto iter = m_heldJoystickButtons[controller_id].begin();iter<m_heldJoystickButtons[controller_id].end();)
iter = *iter == buttoncode ? m_heldJoystickButtons[controller_id].erase(iter) : iter+1;
}
/* mouse-related functions */
glm::vec2 Input::getPosition() const
{
return glm::vec2(m_mouse_position.x,m_mouse_position.y);
}
glm::vec2 Input::getDeltaPosition() const
{
sf::Vector2i delta = m_mouse_position - m_last_mouse_position;
return glm::vec2(delta.x,delta.y);
}
float Input::getDeltaVerticalScroll() const
{
return m_delta_vertical_scroll;
}
void Input::setMouseGrabbed(bool isGrabbed)
{
m_mouseGrabbed = isGrabbed;
if(isGrabbed)
m_last_mouse_position = sf::Vector2i(m_window->getSize())/2;
}
std::vector<int> Input::getControllersConnected() const{
std::vector<int> v;
for(auto &controller : m_heldJoystickButtons)
v.push_back(controller.first);
return v;
}
float Input::getAxisPosition(int device_id, int axis_id)
{
return sf::Joystick::getAxisPosition(device_id, (sf::Joystick::Axis) axis_id);
}
std::wstring Input::getText()
{
return m_buffer;
}
/* ------ */
void Input::test()
{
/* KeyBindings kb = m_keybindings[m_current_context];
int action;
action = kb.getPressedAction(sf::Keyboard::I);
if (action != NO_ACTION)
std::cerr << action << std::endl;
action = kb.getPressedAction(sf::Keyboard::O);
if (action != NO_ACTION)
std::cerr << action << std::endl;*/
}