Files
vibe3_physics/source/input/input_handler.cpp
Sergio c9bcce6f9b style: aplicar fixes de clang-tidy (todo excepto uppercase-literal-suffix)
Corregidos ~2570 issues automáticamente con clang-tidy --fix-errors
más ajustes manuales posteriores:

- modernize: designated-initializers, trailing-return-type, use-auto,
  avoid-c-arrays (→ std::array<>), use-ranges, use-emplace,
  deprecated-headers, use-equals-default, pass-by-value,
  return-braced-init-list, use-default-member-init
- readability: math-missing-parentheses, implicit-bool-conversion,
  braces-around-statements, isolate-declaration, use-std-min-max,
  identifier-naming, else-after-return, redundant-casting,
  convert-member-functions-to-static, make-member-function-const,
  static-accessed-through-instance
- performance: avoid-endl, unnecessary-value-param, type-promotion,
  inefficient-vector-operation
- dead code: XOR_KEY (orphan tras eliminar encryptData/decryptData),
  dead stores en engine.cpp y png_shape.cpp
- NOLINT justificado en 10 funciones con alta complejidad cognitiva
  (initialize, render, main, processEvents, update×3, performDemoAction,
  randomizeOnDemoStart, renderDebugHUD, AppLogo::update)

Compilación: gcc -Wall sin warnings. clang-tidy: 0 issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:52:07 +01:00

331 lines
11 KiB
C++

#include "input_handler.hpp"
#include <SDL3/SDL_keycode.h> // for SDL_Keycode
#include <string> // for std::string, std::to_string
#include "defines.hpp" // for KIOSK_NOTIFICATION_TEXT
#include "engine.hpp" // for Engine
#include "external/mouse.hpp" // for Mouse namespace
auto InputHandler::processEvents(Engine& engine) -> bool { // NOLINT(readability-function-cognitive-complexity)
SDL_Event event;
while (SDL_PollEvent(&event)) {
// Procesar eventos de ratón (auto-ocultar cursor)
Mouse::handleEvent(event);
// Salir del bucle si se detecta una petición de cierre
if (event.type == SDL_EVENT_QUIT) {
return true; // Solicitar salida
}
// Procesar eventos de teclado
if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 0) {
switch (event.key.key) {
case SDLK_ESCAPE:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
break;
}
return true; // Solicitar salida
case SDLK_SPACE:
engine.pushBallsAwayFromGravity();
break;
case SDLK_G:
engine.handleGravityToggle();
break;
// Controles de dirección de gravedad con teclas de cursor
case SDLK_UP:
engine.handleGravityDirectionChange(GravityDirection::UP, "Gravedad arriba");
break;
case SDLK_DOWN:
engine.handleGravityDirectionChange(GravityDirection::DOWN, "Gravedad abajo");
break;
case SDLK_LEFT:
engine.handleGravityDirectionChange(GravityDirection::LEFT, "Gravedad izquierda");
break;
case SDLK_RIGHT:
engine.handleGravityDirectionChange(GravityDirection::RIGHT, "Gravedad derecha");
break;
case SDLK_V:
engine.toggleVSync();
break;
case SDLK_H:
engine.toggleHelp(); // Toggle ayuda de teclas
break;
// Toggle Física ↔ Última Figura (antes era C)
case SDLK_F:
engine.toggleShapeMode();
break;
// Selección directa de figuras 3D
case SDLK_Q:
engine.activateShape(ShapeType::SPHERE, "Esfera");
break;
case SDLK_W:
engine.activateShape(ShapeType::LISSAJOUS, "Lissajous");
break;
case SDLK_E:
engine.activateShape(ShapeType::HELIX, "Hélice");
break;
case SDLK_R:
engine.activateShape(ShapeType::TORUS, "Toroide");
break;
case SDLK_T:
engine.activateShape(ShapeType::CUBE, "Cubo");
break;
case SDLK_Y:
engine.activateShape(ShapeType::CYLINDER, "Cilindro");
break;
case SDLK_U:
engine.activateShape(ShapeType::ICOSAHEDRON, "Icosaedro");
break;
case SDLK_I:
engine.activateShape(ShapeType::ATOM, "Átomo");
break;
case SDLK_O:
// engine.activateShape(ShapeType::PNG_SHAPE, "Forma PNG");
break;
// Toggle Modo Boids (comportamiento de enjambre)
case SDLK_B:
engine.toggleBoidsMode();
break;
// Ciclar temas de color (movido de B a C)
case SDLK_C: {
// Detectar si Shift está presionado
SDL_Keymod modstate = SDL_GetModState();
if ((modstate & SDL_KMOD_SHIFT) != 0u) {
// Shift+C: Ciclar hacia atrás (tema anterior)
engine.cycleTheme(false);
} else {
// C solo: Ciclar hacia adelante (tema siguiente)
engine.cycleTheme(true);
}
} break;
// Temas de colores con teclado numérico (con transición suave)
case SDLK_KP_1:
engine.switchThemeByNumpad(1);
break;
case SDLK_KP_2:
engine.switchThemeByNumpad(2);
break;
case SDLK_KP_3:
engine.switchThemeByNumpad(3);
break;
case SDLK_KP_4:
engine.switchThemeByNumpad(4);
break;
case SDLK_KP_5:
engine.switchThemeByNumpad(5);
break;
case SDLK_KP_6:
engine.switchThemeByNumpad(6);
break;
case SDLK_KP_7:
engine.switchThemeByNumpad(7);
break;
case SDLK_KP_8:
engine.switchThemeByNumpad(8);
break;
case SDLK_KP_9:
engine.switchThemeByNumpad(9);
break;
case SDLK_KP_0:
engine.switchThemeByNumpad(0);
break;
// Toggle de página de temas (Numpad Enter)
case SDLK_KP_ENTER:
engine.toggleThemePage();
break;
// Cambio de sprite/textura dinámico
case SDLK_N:
engine.switchTexture();
break;
// Control de escala de figura (solo en modo SHAPE)
case SDLK_KP_PLUS:
engine.handleShapeScaleChange(true); // Aumentar
break;
case SDLK_KP_MINUS:
engine.handleShapeScaleChange(false); // Disminuir
break;
case SDLK_KP_MULTIPLY:
engine.resetShapeScale();
break;
case SDLK_KP_DIVIDE:
engine.toggleDepthZoom();
break;
// Cambio de número de pelotas (escenarios 1-8)
case SDLK_1:
engine.changeScenario(0, "10 pelotas");
break;
case SDLK_2:
engine.changeScenario(1, "50 pelotas");
break;
case SDLK_3:
engine.changeScenario(2, "100 pelotas");
break;
case SDLK_4:
engine.changeScenario(3, "500 pelotas");
break;
case SDLK_5:
engine.changeScenario(4, "1.000 pelotas");
break;
case SDLK_6:
engine.changeScenario(5, "5.000 pelotas");
break;
case SDLK_7:
engine.changeScenario(6, "10.000 pelotas");
break;
case SDLK_8:
engine.changeScenario(7, "50.000 pelotas");
break;
case SDLK_9:
if (engine.isCustomScenarioEnabled()) {
std::string custom_notif = std::to_string(engine.getCustomScenarioBalls()) + " pelotas";
engine.changeScenario(CUSTOM_SCENARIO_IDX, custom_notif.c_str());
}
break;
// Controles de zoom dinámico (solo si no estamos en fullscreen)
case SDLK_F1:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.handleZoomOut();
}
break;
case SDLK_F2:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.handleZoomIn();
}
break;
// Control de pantalla completa
case SDLK_F3:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.toggleFullscreen();
}
break;
// Modo real fullscreen (cambia resolución interna)
case SDLK_F4:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.toggleRealFullscreen();
}
break;
// Toggle PostFX activo/inactivo
case SDLK_F5:
engine.handlePostFXToggle();
break;
// Toggle escalado entero/estirado (solo en fullscreen F3)
case SDLK_F6:
engine.toggleIntegerScaling();
break;
// Redimensionar campo de juego (tamaño lógico + físico)
case SDLK_F7:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.fieldSizeDown();
}
break;
case SDLK_F8:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
} else {
engine.fieldSizeUp();
}
break;
// Toggle Modo DEMO COMPLETO (auto-play) o Pausar tema dinámico (Shift+D)
case SDLK_D:
// Shift+D = Pausar tema dinámico
if ((event.key.mod & SDL_KMOD_SHIFT) != 0u) {
engine.pauseDynamicTheme();
} else {
// D sin Shift = Toggle DEMO ↔ SANDBOX
engine.toggleDemoMode();
}
break;
// Toggle Modo DEMO LITE (solo física/figuras)
case SDLK_L:
engine.toggleDemoLiteMode();
break;
// Toggle Modo LOGO (easter egg - marca de agua)
case SDLK_K:
engine.toggleLogoMode();
break;
// Ciclar presets PostFX (vinyeta/scanlines/cromàtica/complet/desactivat)
case SDLK_X:
engine.handlePostFXCycle();
break;
// Toggle Debug Display (movido de H a F12)
case SDLK_F12:
engine.toggleDebug();
break;
}
}
}
return false; // No se solicitó salida
}