//
// SFML SCANCODE TESTING
//
// by Hapaxia (2023)
// https://linktr.ee/hapaxia
//
//
//
// INSTRUCTIONS:
// Keys are shown visually showing the name of each key. The default value for each key's scancode is -1 (unknown)
// Click on a key on the screen and then press that key. This sets the scancode for that key.
// After it has been set, whenever that key is pressed, the key on the screen is highlighted (red).
// When clicking on a key, 'set scancode mode' is enabled. This is where you press the key to set the scancode.
// If you press the right mouse button in 'set scancode mode', you reset the scancode back to -1.
// If you press the middle mouse button in 'set scancode mode', all of the scancodes are pre-filled. These may not fully match your setup.
// If you press the middle mouse button with the left ALT key when NOT in 'set scancode mode', all of the scancodes are reset to -1.
// If you press F1 when NOT in 'set scancode mode', the key's labels toggle between being the key names and showing the scancodes for the keys.
//
// WHEN NOT IN 'SET SCANCODE MODE':
// [ESC] close program. all scancodes are lost.
// [F1] toggle key labels between key names and scancodes.
// LMB (on a key) enable 'set scancode mode'.
// [L ALT] + MMB reset ALL scancodes.
//
// WHEN IN 'SET SCANCODE MODE':
// [ANY] set scancode for the chosen (clicked) key to the scancode of the pressed key.
// RMB reset scancode for the chosen (clicked) key.
// MMB pre-fill scancodes.
//
// NOTE:
// Keys are setup in a specific arrangement but 20 spare keys (or "extra pads") are provided to be used for keys not available in the given arrangement.
// This code is designed for use with SFML v2.6.x
//
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
namespace
{
const sf::Vector2u windowSize{ 960u, 540u };
} // namespace
class Keyboard : public sf::Drawable, public sf::Transformable
{
public:
Keyboard()
: m_showCodes{ false }
, m_keys()
, m_font{ nullptr }
, m_boxesVertices()
, m_texts()
{
}
void setFont(sf::Font& font) { m_font = &font; }
void update() { priv_updateGraphics(); }
void setShowCodes(bool showCodes)
{
m_showCodes = showCodes;
}
void addKey(const std::string& name, const sf::FloatRect box, const sf::Vector2f textScale = { 1.f, 1.f }, const float textRotation = 0.f, const int code = -1, const bool isHighlighted = false)
{
m_keys[name] = { code, box, textScale, textRotation, isHighlighted };
}
void reboxKey(const std::string& name, const sf::FloatRect box)
{
if (m_keys.find(name) != m_keys.end())
m_keys[name].box = box;
}
void setTextScale(const std::string& name, const sf::Vector2f textScale)
{
if (m_keys.find(name) != m_keys.end())
m_keys[name].textScale = textScale;
}
void setTextRotation(const std::string& name, const float textRotation)
{
if (m_keys.find(name) != m_keys.end())
m_keys[name].textRotation = textRotation;
}
void setCode(const std::string& name, const int code)
{
if (m_keys.find(name) != m_keys.end())
m_keys[name].code = code;
}
void setIsHighlighted(const std::string& name, const bool isHighlighted)
{
if (m_keys.find(name) != m_keys.end())
m_keys[name].isHighlighted = isHighlighted;
}
std::string getKeyAt(const sf::Vector2f position) const
{
for (auto& key : m_keys)
{
if (key.second.box.contains(getInverseTransform().transformPoint(position)))
return key.first;
}
return "";
}
bool getIsHighlighted(const std::string& name) const
{
if (m_keys.find(name) != m_keys.end())
return m_keys.at(name).isHighlighted;
else
return false;
}
int getCode(const std::string& name) const
{
if (m_keys.find(name) != m_keys.end())
return m_keys.at(name).code;
else
return -1;
}
sf::Vector2f getTextScale(const std::string& name) const
{
if (m_keys.find(name) != m_keys.end())
return m_keys.at(name).textScale;
else
return sf::Vector2f();
}
sf::FloatRect getBox(const std::string& name) const
{
if (m_keys.find(name) != m_keys.end())
return m_keys.at(name).box;
else
return sf::FloatRect();
}
std::string getNameFromKeycode(const sf::Keyboard::Scancode scancode) const
{
auto k{ std::find_if(std::begin(m_keys), std::end(m_keys), [scancode](auto key) { return (static_cast<int>(scancode) == key.second.code); }) };
if (k == m_keys.end())
return "";
else
return k->first;
}
void resetAllCodes()
{
for (auto& k : m_keys)
{
k.second.code = -1;
k.second.isHighlighted = false;
}
}
private:
bool m_showCodes;
struct Key
{
int code{ -1 };
sf::FloatRect box;
sf::Vector2f textScale{ 1.f, 1.f };
float textRotation{ 0.f };
bool isHighlighted{ false };
};
std::unordered_map<std::string, Key> m_keys;
sf::Font* m_font;
std::vector<sf::Vertex> m_boxesVertices;
std::vector<sf::Text> m_texts;
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
states.transform = getTransform();
target.draw(m_boxesVertices.data(), m_boxesVertices.size(), sf::PrimitiveType::Triangles, states);
for (auto& text : m_texts)
target.draw(text, states);
}
void priv_updateGraphics()
{
priv_updateTexts();
priv_updateBoxVertices();
}
void priv_updateTexts()
{
m_texts.resize(m_keys.size());
std::size_t i{ 0u };
for (auto& key : m_keys)
{
m_texts[i].setFont(*m_font);
m_texts[i].setFillColor(sf::Color::Blue);
m_texts[i].setString(m_showCodes ? std::to_string(key.second.code) : key.first);
const sf::FloatRect localBounds{ m_texts[i].getLocalBounds() };
m_texts[i].setOrigin((sf::Vector2f{ localBounds.width, localBounds.height } / 2.f) + sf::Vector2f{ localBounds.left, localBounds.top });
m_texts[i].setPosition((sf::Vector2f{ key.second.box.width, key.second.box.height } / 2.f) + sf::Vector2f{ key.second.box.left, key.second.box.top });
//m_texts[i].setOrigin({ localBounds.left, localBounds.top });
//m_texts[i].setPosition({ key.second.box.left, key.second.box.top });
m_texts[i].setScale(m_showCodes ? sf::Vector2f{ 1.f, 1.f } : key.second.textScale);
m_texts[i].setRotation(m_showCodes ? 0.f : key.second.textRotation);
++i;
}
}
void priv_updateBoxVertices()
{
m_boxesVertices.reserve(m_keys.size());
for (auto& key : m_keys)
{
float left{ key.second.box.left };
float top{ key.second.box.top };
float right{ left + key.second.box.width };
float bottom{ top + key.second.box.height };
sf::Color color{ key.second.isHighlighted ? sf::Color::Red : sf::Color::Yellow };
m_boxesVertices.push_back(sf::Vertex({ right, top }, color));
m_boxesVertices.push_back(sf::Vertex({ left, top }, color));
m_boxesVertices.push_back(sf::Vertex({ left, bottom }, color));
m_boxesVertices.push_back(sf::Vertex({ left, bottom }, color));
m_boxesVertices.push_back(sf::Vertex({ right, bottom }, color));
m_boxesVertices.push_back(sf::Vertex({ right, top }, color));
}
}
};
void setupKeyboardKeys(Keyboard& keyboard)
{
const std::vector<std::string> keyNameMap
{
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]",
"A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "#",
"Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "R SHIFT", "\\"
};
const std::vector<std::string> functionKeyNameMap
{
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"
};
const std::vector<std::string> numpadKeyNameMap
{
"_NUM_\n_LOCK_", "_/_", "_*_",
"_7_", "_8_", "_9_",
"_4_", "_5_", "_6_",
"_1_", "_2_", "_3_"
};
const sf::Vector2f standardBoxSize{ 50.f, 50.f };
constexpr float verticalStep{ 60.f };
constexpr float horizontalStep{ 60.f };
constexpr float basicShearStep{ 25.f };
const sf::Vector2f offsetOneKey{ horizontalStep, 0.f };
const float offsetXInsertKeyFromOneKey{ 14.25f * horizontalStep };
const float offsetXNumpadNumlockFromOneKey{ 17.5f * horizontalStep };
// MAIN KEYS
for (std::size_t y{ 0u }; y < 4u; ++y)
{
for (std::size_t x{ 0u }; x < 12u; ++x)
keyboard.addKey(keyNameMap[y * 12u + x], sf::FloatRect{ offsetOneKey + sf::Vector2f{ (x * horizontalStep) + (y * basicShearStep), (y * verticalStep) }, standardBoxSize });
}
// MOVE FINAL KEY \ TO LEFT SIDE
keyboard.reboxKey("\\", sf::FloatRect{ offsetOneKey + sf::Vector2f{ -horizontalStep + basicShearStep * 3.f, keyboard.getBox("\\").top }, standardBoxSize });
// FIX RIGHT SIDE KEYS
keyboard.reboxKey("]", sf::FloatRect{ { keyboard.getBox("]").left , keyboard.getBox("]").top }, { keyboard.getBox("]").width + basicShearStep, keyboard.getBox("]").height } });
keyboard.reboxKey("R SHIFT", sf::FloatRect{ { keyboard.getBox("R SHIFT").left , keyboard.getBox("R SHIFT").top }, { standardBoxSize.x + 3.f * horizontalStep - 3.f * basicShearStep, keyboard.getBox("R SHIFT").height } });
// BIG RIGHT SIDE KEYS
keyboard.addKey("BACKSPACE", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (12.f * horizontalStep) + (0.f * basicShearStep), (0.f * verticalStep) }, { standardBoxSize.x + horizontalStep, standardBoxSize.y } }, { 0.6f, 1.f });
keyboard.addKey("ENTER", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (12.f * horizontalStep) + (2.f * basicShearStep), (1.f * verticalStep) }, { standardBoxSize.x + horizontalStep - 2.f * basicShearStep, standardBoxSize.y + verticalStep } }, { 0.7f, 1.f }, 90.f);
// LEFT SIDE KEYS
keyboard.addKey("`", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (0.f * verticalStep) }, standardBoxSize });
keyboard.addKey("TAB", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (1.f * verticalStep) }, { standardBoxSize.x + basicShearStep, standardBoxSize.y } });
keyboard.addKey("CAPS\nLOCK", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (2.f * verticalStep) }, { standardBoxSize.x + basicShearStep * 2.f, standardBoxSize.y } }, { 1.f, 0.6f });
keyboard.addKey("L SHIFT", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (3.f * verticalStep) }, { standardBoxSize.x + basicShearStep * 3.f - horizontalStep, standardBoxSize.y } }, { 0.5f, 1.f });
// TOP LINE
constexpr float topLineStepMultiplier{ 1.3f };
keyboard.addKey("ESC", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (-topLineStepMultiplier * verticalStep) }, standardBoxSize }, { 0.7f, 1.f });
for (std::size_t q{ 0u }; q < 3u; ++q)
{
for (std::size_t i{ 0u }; i < 4; ++i)
keyboard.addKey(functionKeyNameMap[q * 4u + i], sf::FloatRect{ offsetOneKey + sf::Vector2f{ (1u + i + (4.5f * q)) * horizontalStep, (-topLineStepMultiplier * verticalStep) }, standardBoxSize });
}
keyboard.addKey("ESC", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * basicShearStep), (-topLineStepMultiplier * verticalStep) }, standardBoxSize }, { 0.7f, 1.f });
// TOP LINE CONTROL COLUMN
keyboard.addKey("PRT\nSCR", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (0.f * horizontalStep), (-topLineStepMultiplier * verticalStep) }, standardBoxSize }, { 0.7f, 0.7f });
keyboard.addKey("SCRL\nLOCK", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (1.f * horizontalStep), (-topLineStepMultiplier * verticalStep)}, standardBoxSize }, { 0.5f, 0.7f });
keyboard.addKey("PAUSE\nBREAK", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (2.f * horizontalStep), (-topLineStepMultiplier * verticalStep)}, standardBoxSize }, { 0.4f, 0.7f });
// MAIN TOP CONTROL COLUMN
keyboard.addKey("INS", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (0.f * horizontalStep), (0.f * verticalStep) }, standardBoxSize }, { 0.8f, 1.f });
keyboard.addKey("HOME", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (1.f * horizontalStep), (0.f * verticalStep) }, standardBoxSize }, { 0.5f, 1.f });
keyboard.addKey("PGUP", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (2.f * horizontalStep), (0.f * verticalStep) }, standardBoxSize }, { 0.5f, 1.f });
keyboard.addKey("DEL", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (0.f * horizontalStep), (1.f * verticalStep) }, standardBoxSize }, { 0.7f, 1.f });
keyboard.addKey("END", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (1.f * horizontalStep), (1.f * verticalStep) }, standardBoxSize }, { 0.7f, 1.f });
keyboard.addKey("PGDN", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (2.f * horizontalStep), (1.f * verticalStep) }, standardBoxSize }, { 0.5f, 1.f });
// BOTTOM CONTROL COLUMN - ARROW KEYS
keyboard.addKey("UP", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (1.f * horizontalStep), (3.f * verticalStep) }, standardBoxSize }, { 1.f, 1.f });
keyboard.addKey("LEFT", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (0.f * horizontalStep), (4.f * verticalStep) }, standardBoxSize }, { 0.6f, 1.f });
keyboard.addKey("DOWN", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (1.f * horizontalStep), (4.f * verticalStep) }, standardBoxSize }, { 0.5f, 1.f });
keyboard.addKey("RIGHT", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXInsertKeyFromOneKey + (2.f * horizontalStep), (4.f * verticalStep) }, standardBoxSize }, { 0.5f, 1.f });
// NUMBER PAD
for (std::size_t y{ 0u }; y < 4u; ++y)
{
for (std::size_t x{ 0u }; x < 3; ++x)
keyboard.addKey(numpadKeyNameMap[y * 3u + x], sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (x * horizontalStep), (y * verticalStep) }, standardBoxSize }, { 0.7f, 1.f });
}
keyboard.setTextScale(numpadKeyNameMap[0u], { 0.4f, 0.6f });
keyboard.addKey("_-_", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (3.f * horizontalStep), (0.f * verticalStep)}, standardBoxSize }, { 0.7f, 1.f });
keyboard.addKey("_._", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (2.f * horizontalStep), (4.f * verticalStep)}, standardBoxSize }, { 0.7f, 1.f });
keyboard.addKey("_+_", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (3.f * horizontalStep), (1.f * verticalStep)}, { standardBoxSize.x, standardBoxSize.y + verticalStep } }, { 0.7f, 1.f });
keyboard.addKey("_ENTER_", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (3.f * horizontalStep), (3.f * verticalStep)}, { standardBoxSize.x, standardBoxSize.y + verticalStep } }, { 0.7f, 1.f }, 90.f);
keyboard.addKey("_0_", sf::FloatRect{ offsetOneKey + sf::Vector2f{ offsetXNumpadNumlockFromOneKey + (0.f * horizontalStep), (4.f * verticalStep)}, { standardBoxSize.x + horizontalStep, standardBoxSize.y } }, { 1.f, 1.f });
// BOTTOM ROW
const float ctrlKeyWidth{ standardBoxSize.x + basicShearStep * 3.f - horizontalStep };
const float keyHorizontalGap{ horizontalStep - standardBoxSize.x };
const float mainWidth{ horizontalStep * 14.f + standardBoxSize.x };
keyboard.addKey("L CTRL", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (0.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.5f, 1.f });
keyboard.addKey("L SYS", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (1.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.6f, 1.f });
keyboard.addKey("L ALT", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (2.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.7f, 1.f });
keyboard.addKey("SPACE", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + (3.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { mainWidth - (ctrlKeyWidth * 7.f) - (keyHorizontalGap * 7.f), standardBoxSize.y} }, { 2.f, 1.f });
keyboard.addKey("R CTRL", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + mainWidth + keyHorizontalGap - (1.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.5f, 1.f });
keyboard.addKey("R SYS", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + mainWidth + keyHorizontalGap - (2.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.6f, 1.f });
keyboard.addKey("FN", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + mainWidth + keyHorizontalGap - (3.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 1.f, 1.f });
keyboard.addKey("R ALT", sf::FloatRect{ offsetOneKey + sf::Vector2f{ (-1.f * horizontalStep) + mainWidth + keyHorizontalGap - (4.f * (ctrlKeyWidth + keyHorizontalGap)), (4.f * verticalStep) }, { ctrlKeyWidth, standardBoxSize.y } }, { 0.6f, 1.f });
// EXTRA PAD
sf::Vector2f extraPadOffsetFromOneKey{ standardBoxSize * 7.f };
sf::Vector2u extraPadSize{ 5u, 4u };
sf::Vector2f extraPadBoxSize{ standardBoxSize * 2.f };
sf::Vector2f extraPadStep{ extraPadBoxSize.x + (horizontalStep - standardBoxSize.x), extraPadBoxSize.y + (verticalStep - standardBoxSize.y) };
for (std::size_t y{ 0u }; y < extraPadSize.y; ++y)
{
for (std::size_t x{ 0u }; x < extraPadSize.x; ++x)
{
std::string n{ "EXTRA\nPAD " + std::to_string(y * extraPadSize.x + x) };
keyboard.addKey(n, sf::FloatRect{ offsetOneKey + extraPadOffsetFromOneKey + sf::Vector2f{ (x * extraPadStep.x), (y * extraPadStep.y) }, extraPadBoxSize }, { 0.8f, 1.f });
}
}
}
void preFillCodes(Keyboard& keyboard)
{
keyboard.setCode("ESC", static_cast<int>(sf::Keyboard::Scancode::Escape));
keyboard.setCode("F1", static_cast<int>(sf::Keyboard::Scancode::F1));
keyboard.setCode("F2", static_cast<int>(sf::Keyboard::Scancode::F2));
keyboard.setCode("F3", static_cast<int>(sf::Keyboard::Scancode::F3));
keyboard.setCode("F4", static_cast<int>(sf::Keyboard::Scancode::F4));
keyboard.setCode("F5", static_cast<int>(sf::Keyboard::Scancode::F5));
keyboard.setCode("F6", static_cast<int>(sf::Keyboard::Scancode::F6));
keyboard.setCode("F7", static_cast<int>(sf::Keyboard::Scancode::F7));
keyboard.setCode("F8", static_cast<int>(sf::Keyboard::Scancode::F8));
keyboard.setCode("F9", static_cast<int>(sf::Keyboard::Scancode::F9));
keyboard.setCode("F10", static_cast<int>(sf::Keyboard::Scancode::F10));
keyboard.setCode("F11", static_cast<int>(sf::Keyboard::Scancode::F11));
keyboard.setCode("F12", static_cast<int>(sf::Keyboard::Scancode::F12));
keyboard.setCode("`", static_cast<int>(sf::Keyboard::Scancode::Grave));
keyboard.setCode("1", static_cast<int>(sf::Keyboard::Scancode::Num1));
keyboard.setCode("2", static_cast<int>(sf::Keyboard::Scancode::Num2));
keyboard.setCode("3", static_cast<int>(sf::Keyboard::Scancode::Num3));
keyboard.setCode("4", static_cast<int>(sf::Keyboard::Scancode::Num4));
keyboard.setCode("5", static_cast<int>(sf::Keyboard::Scancode::Num5));
keyboard.setCode("6", static_cast<int>(sf::Keyboard::Scancode::Num6));
keyboard.setCode("7", static_cast<int>(sf::Keyboard::Scancode::Num7));
keyboard.setCode("8", static_cast<int>(sf::Keyboard::Scancode::Num8));
keyboard.setCode("9", static_cast<int>(sf::Keyboard::Scancode::Num9));
keyboard.setCode("0", static_cast<int>(sf::Keyboard::Scancode::Num0));
keyboard.setCode("-", static_cast<int>(sf::Keyboard::Scancode::Hyphen));
keyboard.setCode("=", static_cast<int>(sf::Keyboard::Scancode::Equal));
keyboard.setCode("BACKSPACE", static_cast<int>(sf::Keyboard::Scancode::Backspace));
keyboard.setCode("TAB", static_cast<int>(sf::Keyboard::Scancode::Tab));
keyboard.setCode("Q", static_cast<int>(sf::Keyboard::Scancode::Q));
keyboard.setCode("W", static_cast<int>(sf::Keyboard::Scancode::W));
keyboard.setCode("E", static_cast<int>(sf::Keyboard::Scancode::E));
keyboard.setCode("R", static_cast<int>(sf::Keyboard::Scancode::R));
keyboard.setCode("T", static_cast<int>(sf::Keyboard::Scancode::T));
keyboard.setCode("Y", static_cast<int>(sf::Keyboard::Scancode::Y));
keyboard.setCode("U", static_cast<int>(sf::Keyboard::Scancode::U));
keyboard.setCode("I", static_cast<int>(sf::Keyboard::Scancode::I));
keyboard.setCode("O", static_cast<int>(sf::Keyboard::Scancode::O));
keyboard.setCode("P", static_cast<int>(sf::Keyboard::Scancode::P));
keyboard.setCode("[", static_cast<int>(sf::Keyboard::Scancode::LBracket));
keyboard.setCode("]", static_cast<int>(sf::Keyboard::Scancode::RBracket));
keyboard.setCode("ENTER", static_cast<int>(sf::Keyboard::Scancode::Enter));
keyboard.setCode("CAPS\nLOCK", static_cast<int>(sf::Keyboard::Scancode::CapsLock));
keyboard.setCode("A", static_cast<int>(sf::Keyboard::Scancode::A));
keyboard.setCode("S", static_cast<int>(sf::Keyboard::Scancode::S));
keyboard.setCode("D", static_cast<int>(sf::Keyboard::Scancode::D));
keyboard.setCode("F", static_cast<int>(sf::Keyboard::Scancode::F));
keyboard.setCode("G", static_cast<int>(sf::Keyboard::Scancode::G));
keyboard.setCode("H", static_cast<int>(sf::Keyboard::Scancode::H));
keyboard.setCode("J", static_cast<int>(sf::Keyboard::Scancode::J));
keyboard.setCode("K", static_cast<int>(sf::Keyboard::Scancode::K));
keyboard.setCode("L", static_cast<int>(sf::Keyboard::Scancode::L));
keyboard.setCode(";", static_cast<int>(sf::Keyboard::Scancode::Semicolon));
keyboard.setCode("'", static_cast<int>(sf::Keyboard::Scancode::Apostrophe));
keyboard.setCode("#", static_cast<int>(sf::Keyboard::Scancode::Backslash)); // 45: backslash = hash (#) near Return
keyboard.setCode("L SHIFT", static_cast<int>(sf::Keyboard::Scancode::LShift));
keyboard.setCode("\\", static_cast<int>(sf::Keyboard::Scancode::NonUsBackslash)); // NonUsBackslash = backslash (\) near Z
keyboard.setCode("Z", static_cast<int>(sf::Keyboard::Scancode::Z));
keyboard.setCode("X", static_cast<int>(sf::Keyboard::Scancode::X));
keyboard.setCode("C", static_cast<int>(sf::Keyboard::Scancode::C));
keyboard.setCode("V", static_cast<int>(sf::Keyboard::Scancode::V));
keyboard.setCode("B", static_cast<int>(sf::Keyboard::Scancode::B));
keyboard.setCode("N", static_cast<int>(sf::Keyboard::Scancode::N));
keyboard.setCode("M", static_cast<int>(sf::Keyboard::Scancode::M));
keyboard.setCode(",", static_cast<int>(sf::Keyboard::Scancode::Comma));
keyboard.setCode(".", static_cast<int>(sf::Keyboard::Scancode::Period));
keyboard.setCode("/", static_cast<int>(sf::Keyboard::Scancode::Slash));
keyboard.setCode("R SHIFT", static_cast<int>(sf::Keyboard::Scancode::RShift));
keyboard.setCode("L CTRL", static_cast<int>(sf::Keyboard::Scancode::LControl));
keyboard.setCode("L SYS", static_cast<int>(sf::Keyboard::Scancode::LSystem));
keyboard.setCode("L ALT", static_cast<int>(sf::Keyboard::Scancode::LAlt));
keyboard.setCode("SPACE", static_cast<int>(sf::Keyboard::Scancode::Space));
keyboard.setCode("R ALT", static_cast<int>(sf::Keyboard::Scancode::RAlt));
//keyboard.setCode("FN", static_cast<int>(sf::Keyboard::Scancode::));
keyboard.setCode("R SYS", static_cast<int>(sf::Keyboard::Scancode::Menu));
keyboard.setCode("R CTRL", static_cast<int>(sf::Keyboard::Scancode::RControl));
keyboard.setCode("PRT\nSCR", static_cast<int>(sf::Keyboard::Scancode::PrintScreen));
keyboard.setCode("SCRL\nLOCK", static_cast<int>(sf::Keyboard::Scancode::ScrollLock));
keyboard.setCode("PAUSE\nBREAK", static_cast<int>(sf::Keyboard::Scancode::Pause));
keyboard.setCode("INS", static_cast<int>(sf::Keyboard::Scancode::Insert));
keyboard.setCode("DEL", static_cast<int>(sf::Keyboard::Scancode::Delete));
keyboard.setCode("HOME", static_cast<int>(sf::Keyboard::Scancode::Home));
keyboard.setCode("END", static_cast<int>(sf::Keyboard::Scancode::End));
keyboard.setCode("PGUP", static_cast<int>(sf::Keyboard::Scancode::PageUp));
keyboard.setCode("PGDN", static_cast<int>(sf::Keyboard::Scancode::PageDown));
keyboard.setCode("UP", static_cast<int>(sf::Keyboard::Scancode::Up));
keyboard.setCode("DOWN", static_cast<int>(sf::Keyboard::Scancode::Down));
keyboard.setCode("LEFT", static_cast<int>(sf::Keyboard::Scancode::Left));
keyboard.setCode("RIGHT", static_cast<int>(sf::Keyboard::Scancode::Right));
keyboard.setCode("_1_", static_cast<int>(sf::Keyboard::Scancode::Numpad1));
keyboard.setCode("_2_", static_cast<int>(sf::Keyboard::Scancode::Numpad2));
keyboard.setCode("_3_", static_cast<int>(sf::Keyboard::Scancode::Numpad3));
keyboard.setCode("_4_", static_cast<int>(sf::Keyboard::Scancode::Numpad4));
keyboard.setCode("_5_", static_cast<int>(sf::Keyboard::Scancode::Numpad5));
keyboard.setCode("_6_", static_cast<int>(sf::Keyboard::Scancode::Numpad6));
keyboard.setCode("_7_", static_cast<int>(sf::Keyboard::Scancode::Numpad7));
keyboard.setCode("_8_", static_cast<int>(sf::Keyboard::Scancode::Numpad8));
keyboard.setCode("_9_", static_cast<int>(sf::Keyboard::Scancode::Numpad9));
keyboard.setCode("_0_", static_cast<int>(sf::Keyboard::Scancode::Numpad0));
keyboard.setCode("_NUM_\n_LOCK_", static_cast<int>(sf::Keyboard::Scancode::NumLock));
keyboard.setCode("_/_", static_cast<int>(sf::Keyboard::Scancode::NumpadDivide));
keyboard.setCode("_*_", static_cast<int>(sf::Keyboard::Scancode::NumpadMultiply));
keyboard.setCode("_-_", static_cast<int>(sf::Keyboard::Scancode::NumpadMinus));
keyboard.setCode("_+_", static_cast<int>(sf::Keyboard::Scancode::NumpadPlus));
keyboard.setCode("_._", static_cast<int>(sf::Keyboard::Scancode::NumpadDecimal));
keyboard.setCode("_ENTER_", static_cast<int>(sf::Keyboard::Scancode::NumpadEnter));
keyboard.setCode("EXTRA\nPAD 0", static_cast<int>(sf::Keyboard::Scancode::MediaNextTrack));
keyboard.setCode("EXTRA\nPAD 1", static_cast<int>(sf::Keyboard::Scancode::MediaPreviousTrack));
keyboard.setCode("EXTRA\nPAD 2", static_cast<int>(sf::Keyboard::Scancode::MediaPlayPause));
keyboard.setCode("EXTRA\nPAD 3", static_cast<int>(sf::Keyboard::Scancode::VolumeUp));
keyboard.setCode("EXTRA\nPAD 4", static_cast<int>(sf::Keyboard::Scancode::VolumeDown));
keyboard.setCode("EXTRA\nPAD 5", static_cast<int>(sf::Keyboard::Scancode::HomePage));
keyboard.setCode("EXTRA\nPAD 6", static_cast<int>(sf::Keyboard::Scancode::LaunchMail));
keyboard.setCode("EXTRA\nPAD 7", static_cast<int>(sf::Keyboard::Scancode::LaunchApplication1));
}
int main()
{
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
std::cerr << "Unable to load font file.\n";
return EXIT_FAILURE;
}
sf::Text feedbackText;
feedbackText.setFont(font);
feedbackText.setFillColor(sf::Color::White);
feedbackText.setCharacterSize(30u);
feedbackText.setPosition({ 10.f, 10.f });
feedbackText.setString("");
Keyboard keyboard;
keyboard.setFont(font);
setupKeyboardKeys(keyboard);
keyboard.update();
keyboard.setPosition({ 200.f, 200.f });
bool showCodes{ false };
bool isSetCodeModeActive{ false };
std::string setCodeModeKeyName{ 0u };
sf::View view({ 0.f, 0.f, 1920.f, 1080.f });
sf::RenderWindow window(sf::VideoMode(windowSize.x, windowSize.y), "Keyboard Scancodes");
window.setFramerateLimit(30u);
window.setView(view);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
keyboard.setIsHighlighted(keyboard.getNameFromKeycode(event.key.scancode), true);
keyboard.update();
switch (event.key.code)
{
case sf::Keyboard::Escape:
if (isSetCodeModeActive)
{
keyboard.setCode(setCodeModeKeyName, event.key.scancode);
keyboard.update();
}
else
window.close();
break;
case sf::Keyboard::F1:
if (isSetCodeModeActive)
{
keyboard.setCode(setCodeModeKeyName, event.key.scancode);
keyboard.update();
}
else
{
keyboard.setShowCodes(showCodes = !showCodes);
keyboard.update();
}
break;
default:
if (isSetCodeModeActive)
{
keyboard.setCode(setCodeModeKeyName, event.key.scancode);
keyboard.update();
}
}
isSetCodeModeActive = false;
break;
case sf::Event::KeyReleased:
keyboard.setIsHighlighted(keyboard.getNameFromKeycode(event.key.scancode), false);
keyboard.update();
break;
case sf::Event::MouseButtonPressed:
switch (event.mouseButton.button)
{
case sf::Mouse::Button::Left:
{
const sf::Vector2f mousePosition{ window.mapPixelToCoords({ event.mouseButton.x, event.mouseButton.y }) };
setCodeModeKeyName = keyboard.getKeyAt(mousePosition);
if (setCodeModeKeyName != "")
isSetCodeModeActive = true;
}
break;
case sf::Mouse::Button::Right:
if (isSetCodeModeActive)
{
keyboard.setCode(setCodeModeKeyName, -1);
keyboard.update();
isSetCodeModeActive = false;
}
break;
case sf::Mouse::Button::Middle:
if (isSetCodeModeActive)
preFillCodes(keyboard);
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt))
keyboard.resetAllCodes();
keyboard.update();
isSetCodeModeActive = false;
break;
}
break;
}
}
std::string feedbackTextString;
if (isSetCodeModeActive)
feedbackTextString = "Set Code Mode is currently active";
feedbackText.setString(feedbackTextString);
window.clear();
window.draw(keyboard);
if (isSetCodeModeActive)
window.draw(feedbackText);
window.display();
}
}