| 310 | { |
| 311 | public: |
| 312 | explicit KeyboardView(const sf::Font& font) : m_labels(sf::Keyboard::ScancodeCount, sf::Text(font, "", 14)) |
| 313 | { |
| 314 | // Check all the scancodes are in the matrix exactly once |
| 315 | { |
| 316 | std::unordered_set<sf::Keyboard::Scancode> scancodesInMatrix; |
| 317 | for (const auto& [cells, marginBottom] : m_matrix) |
| 318 | { |
| 319 | for (const auto& [scancode, size, marginRight] : cells) |
| 320 | { |
| 321 | assert(scancodesInMatrix.count(scancode) == 0); |
| 322 | scancodesInMatrix.insert(scancode); |
| 323 | } |
| 324 | } |
| 325 | assert(scancodesInMatrix.size() == sf::Keyboard::ScancodeCount); |
| 326 | } |
| 327 | |
| 328 | // Initialize keys color and label |
| 329 | forEachKey( |
| 330 | [this](sf::Keyboard::Scancode scancode, const sf::FloatRect& rect) |
| 331 | { |
| 332 | const auto scancodeIndex = static_cast<std::size_t>(scancode); |
| 333 | |
| 334 | for (std::size_t vertexIndex = 0u; vertexIndex < 6u; ++vertexIndex) |
| 335 | m_triangles[6u * scancodeIndex + vertexIndex] |
| 336 | .color = sf::Keyboard::delocalize(sf::Keyboard::localize(scancode)) != scancode |
| 337 | ? sf::Color::Red |
| 338 | : sf::Color::White; |
| 339 | |
| 340 | sf::Text& label = m_labels[scancodeIndex]; |
| 341 | label.setString(sf::Keyboard::getDescription(scancode)); |
| 342 | label.setPosition(rect.position + rect.size / 2.f); |
| 343 | |
| 344 | if (rect.size.x < label.getLocalBounds().size.x + padding * 2.f + 2.f) |
| 345 | { |
| 346 | sf::String string = label.getString(); |
| 347 | string.replace(" ", "\n"); |
| 348 | label.setString(string); |
| 349 | } |
| 350 | while (rect.size.x < label.getLocalBounds().size.x + padding * 2.f + 2.f) |
| 351 | label.setCharacterSize(label.getCharacterSize() - 2); |
| 352 | |
| 353 | const sf::FloatRect bounds = label.getLocalBounds(); |
| 354 | label.setOrigin({std::round(bounds.position.x + bounds.size.x / 2.f), |
| 355 | std::round(static_cast<float>(label.getCharacterSize()) / 2.f)}); |
| 356 | }); |
| 357 | } |
| 358 | |
| 359 | void handle(const sf::Event& event) |
| 360 | { |
nothing calls this directly
no test coverage detected