From e6c87ecf877d88474257e117d55cfb204d8e2cd0 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Mon, 2 Mar 2026 23:09:48 +0300 Subject: [PATCH] DrawCamera works on events --- src/DrawCamera.cpp | 67 ++++++++++------- src/DrawCamera.hpp | 6 ++ src/DrawingProgram/DrawingProgram.cpp | 9 +-- .../DrawingProgramSelection.cpp | 72 ++++++++++--------- src/DrawingProgram/Tools/LassoSelectTool.cpp | 4 +- src/DrawingProgram/Tools/LineDrawTool.cpp | 2 +- src/DrawingProgram/Tools/RectSelectTool.cpp | 4 +- src/InputManager.cpp | 11 ++- src/InputManager.hpp | 14 ++-- src/MainProgram.cpp | 5 ++ src/MainProgram.hpp | 1 + src/World.cpp | 14 +++- src/World.hpp | 1 + src/main.cpp | 1 + 14 files changed, 132 insertions(+), 79 deletions(-) diff --git a/src/DrawCamera.cpp b/src/DrawCamera.cpp index 61b68a3..670c330 100755 --- a/src/DrawCamera.cpp +++ b/src/DrawCamera.cpp @@ -108,21 +108,43 @@ void DrawCamera::update_main(World& w) { c.rotate_about(smoothMove.endCenter, smoothMove.end.rotation); smoothMove.occurring = false; } - } else { + if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_COUNTERCLOCKWISE).held && !w.main.input.text.is_accepting_input()) + c.rotate_about(c.from_space(w.main.window.size.cast() * 0.5f), -w.main.deltaTime); + if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_CLOCKWISE).held && !w.main.input.text.is_accepting_input()) + c.rotate_about(c.from_space(w.main.window.size.cast() * 0.5f), w.main.deltaTime); + } + + set_viewing_area(w.main.window.size.cast()); + + if(c.inverseScale < WorldScalar(1)) + w.scale_up_step(); +} + +void DrawCamera::input_key_callback(const InputManager::KeyCallbackArgs& key) { +} + +void DrawCamera::input_mouse_button_on_canvas_callback(World& w, const InputManager::MouseButtonCallbackArgs& button) { + if(!smoothMove.occurring) { bool newIsAccurateZooming = (w.drawProg.controls.middleClickHeld && w.main.input.pen.isDown && w.main.input.pen.buttons[w.main.toolbar.tabletOptions.middleClickButton].held && w.main.toolbar.tabletOptions.zoomWhilePenDownAndButtonHeld) || // Hold middle click (pen button assigned to middle click) while pen is down (w.drawProg.controls.middleClickHeld && w.main.input.key(InputManager::KEY_GENERIC_LCTRL).held) || // Hold middle click/pen button while holding control (w.drawProg.controls.leftClickHeld && w.drawProg.drawTool->get_type() == DrawingProgramToolType::ZOOM); // Hold left click while on zoom tool - if(newIsAccurateZooming && !isAccurateZooming) { - startZoomMousePos = w.get_mouse_world_pos(); + startZoomMousePos = c.from_space(button.pos); startZoomVal = c.inverseScale; startZoomCameraPos = c.pos; } isAccurateZooming = newIsAccurateZooming; + } + else + isAccurateZooming = false; +} + +void DrawCamera::input_mouse_motion_callback(World& w, const InputManager::MouseMotionCallbackArgs& motion) { + if(!smoothMove.occurring) { if(isAccurateZooming && startZoomVal != WorldScalar(0)) { - WorldScalar zoomFactor(std::pow(1.0 + w.main.toolbar.dragZoomSpeed, w.main.toolbar.flipZoomToolDirection ? w.main.input.mouse.move.y() : -w.main.input.mouse.move.y())); + WorldScalar zoomFactor(std::pow(1.0 + w.main.toolbar.dragZoomSpeed, w.main.toolbar.flipZoomToolDirection ? motion.move.y() : -motion.move.y())); if(zoomFactor < WorldScalar(0.000001)) zoomFactor = WorldScalar(0.000001); @@ -136,40 +158,33 @@ void DrawCamera::update_main(World& w) { } } else if(w.drawProg.controls.middleClickHeld || (w.drawProg.controls.leftClickHeld && w.drawProg.drawTool->get_type() == DrawingProgramToolType::PAN)) - c.pos -= c.dir_from_space(w.main.input.mouse.move); - if(w.main.input.mouse.scrollAmount.y() && !w.main.toolbar.io->hoverObstructed) { - // Ignore the value of scrollAmount, since that leads to problems on macOS + c.pos -= c.dir_from_space(motion.move); + } +} - WorldScalar zoomFactor(1.0 + w.main.toolbar.scrollZoomSpeed); +void DrawCamera::input_mouse_wheel_callback(World& w, const InputManager::MouseWheelCallbackArgs& wheel) { + if(!smoothMove.occurring && wheel.tickAmount.y() && w.main.toolbar.check_if_position_isnt_obstructed(wheel.mousePos)) { + WorldVec mouseWorldPos = c.from_space(wheel.mousePos); + WorldScalar zoomFactor(1.0 + w.main.toolbar.scrollZoomSpeed); - if(zoomFactor < WorldScalar(0.000001)) - zoomFactor = WorldScalar(0.000001); + if(zoomFactor < WorldScalar(0.000001)) + zoomFactor = WorldScalar(0.000001); - if(zoomFactor != WorldScalar(0)) { - if(w.main.input.mouse.scrollAmount.y() < 0.0) - zoomFactor = WorldScalar(1) / zoomFactor; + if(zoomFactor != WorldScalar(0)) { + if(wheel.tickAmount.y() < 0.0) + zoomFactor = WorldScalar(1) / zoomFactor; + for(int i = 0; i < std::abs(wheel.tickAmount.y()); i++) { c.scale(zoomFactor); if(c.inverseScale < WorldScalar(0.0001)) c.inverseScale = WorldScalar(0.0001); else { - WorldVec mVec = c.pos - w.get_mouse_world_pos(); - c.pos = w.get_mouse_world_pos() + mVec / zoomFactor; + WorldVec mVec = c.pos - mouseWorldPos; + c.pos = mouseWorldPos + mVec / zoomFactor; } } } - if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_COUNTERCLOCKWISE).held && !w.main.input.text.is_accepting_input()) { - c.rotate_about(c.from_space(w.main.window.size.cast() * 0.5f), -w.main.deltaTime); - } - if(w.main.input.key(InputManager::KEY_CAMERA_ROTATE_CLOCKWISE).held && !w.main.input.text.is_accepting_input()) { - c.rotate_about(c.from_space(w.main.window.size.cast() * 0.5f), w.main.deltaTime); - } } - - set_viewing_area(w.main.window.size.cast()); - - if(c.inverseScale < WorldScalar(1)) - w.scale_up_step(); } void DrawCamera::save_file(cereal::PortableBinaryOutputArchive& a, const World& w) const { diff --git a/src/DrawCamera.hpp b/src/DrawCamera.hpp index 673a23a..67bb354 100644 --- a/src/DrawCamera.hpp +++ b/src/DrawCamera.hpp @@ -5,6 +5,7 @@ #include #include "CoordSpaceHelper.hpp" #include +#include "InputManager.hpp" using namespace Eigen; @@ -28,6 +29,11 @@ class DrawCamera { void save_file(cereal::PortableBinaryOutputArchive& a, const World& w) const; void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version, World& w); + + void input_key_callback(const InputManager::KeyCallbackArgs& key); + void input_mouse_button_on_canvas_callback(World& w, const InputManager::MouseButtonCallbackArgs& button); + void input_mouse_motion_callback(World& w, const InputManager::MouseMotionCallbackArgs& motion); + void input_mouse_wheel_callback(World& w, const InputManager::MouseWheelCallbackArgs& wheel); private: struct SmoothMove { CoordSpaceHelper start; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index dae6d2d..46f7111 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -55,7 +55,7 @@ void DrawingProgram::on_tab_out() { void DrawingProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { bool isHoveringOverCanvas = world.main.toolbar.check_if_position_isnt_obstructed(button.pos); if(isHoveringOverCanvas) { - if(button.button == InputManager::MouseButtonCallbackArgs::Button::RIGHT) { + if(button.button == InputManager::MouseButton::RIGHT) { if(button.down) { if(world.main.toolbar.rightClickPopupLocation) world.main.toolbar.rightClickPopupLocation = std::nullopt; @@ -66,14 +66,15 @@ void DrawingProgram::input_mouse_button_callback(const InputManager::MouseButton else { if(button.down) world.main.toolbar.rightClickPopupLocation = std::nullopt; - if(button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT) + if(button.button == InputManager::MouseButton::LEFT) controls.leftClickHeld = button.down; - else if(button.button == InputManager::MouseButtonCallbackArgs::Button::MIDDLE) + else if(button.button == InputManager::MouseButton::MIDDLE) controls.middleClickHeld = button.down; drawTool->input_mouse_button_on_canvas_callback(button); + world.drawData.cam.input_mouse_button_on_canvas_callback(world, button); } } - else if(!button.down && button.button != InputManager::MouseButtonCallbackArgs::Button::RIGHT) { + else if(!button.down && button.button != InputManager::MouseButton::RIGHT) { drawTool->input_mouse_button_on_canvas_callback(button); } } diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index f90c9a6..270ec41 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -421,7 +421,7 @@ void DrawingProgramSelection::input_key_callback_display_selection(const InputMa } void DrawingProgramSelection::input_mouse_button_on_canvas_callback_modify_selection(const InputManager::MouseButtonCallbackArgs& button) { - if(button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT) { + if(button.button == InputManager::MouseButton::LEFT && is_something_selected()) { switch(transformOpHappening) { case TransformOperation::NONE: { if(button.down && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { @@ -466,7 +466,7 @@ void DrawingProgramSelection::input_mouse_button_on_canvas_callback_modify_selec } void DrawingProgramSelection::input_mouse_motion_callback_modify_selection(const InputManager::MouseMotionCallbackArgs& motion) { - if(drawP.world.main.input.mouse.leftDown) { + if(drawP.world.main.input.mouse.leftDown && is_something_selected()) { rebuild_cam_space(); switch(transformOpHappening) { @@ -510,41 +510,43 @@ void DrawingProgramSelection::input_mouse_motion_callback_modify_selection(const } void DrawingProgramSelection::translate_key(unsigned keyPressed, bool pressed) { - if(pressed) { - constexpr float KEY_TRANSLATE_MAGNITUDE = 5.0f; - Vector2f moveVec; - switch(keyPressed) { - case InputManager::KEY_TEXT_UP: - moveVec = {0.0f, -1.0f}; - break; - case InputManager::KEY_TEXT_DOWN: - moveVec = {0.0f, 1.0f}; - break; - case InputManager::KEY_TEXT_RIGHT: - moveVec = {1.0f, 0.0f}; - break; - case InputManager::KEY_TEXT_LEFT: - moveVec = {-1.0f, 0.0f}; - break; - } - moveVec *= KEY_TRANSLATE_MAGNITUDE; - if(transformOpHappening == TransformOperation::NONE) { - translateData.startPos = drawP.world.drawData.cam.c.dir_from_space(moveVec); - translateData.translateWithKeys = true; - transformOpHappening = TransformOperation::TRANSLATE; - check_add_stroke_color_change_undo(); + if(is_something_selected()) { + if(pressed) { + constexpr float KEY_TRANSLATE_MAGNITUDE = 5.0f; + Vector2f moveVec; + switch(keyPressed) { + case InputManager::KEY_TEXT_UP: + moveVec = {0.0f, -1.0f}; + break; + case InputManager::KEY_TEXT_DOWN: + moveVec = {0.0f, 1.0f}; + break; + case InputManager::KEY_TEXT_RIGHT: + moveVec = {1.0f, 0.0f}; + break; + case InputManager::KEY_TEXT_LEFT: + moveVec = {-1.0f, 0.0f}; + break; + } + moveVec *= KEY_TRANSLATE_MAGNITUDE; + if(transformOpHappening == TransformOperation::NONE) { + translateData.startPos = drawP.world.drawData.cam.c.dir_from_space(moveVec); + translateData.translateWithKeys = true; + transformOpHappening = TransformOperation::TRANSLATE; + check_add_stroke_color_change_undo(); + } + else if(transformOpHappening == TransformOperation::TRANSLATE && translateData.translateWithKeys) { + moveVec *= KEY_TRANSLATE_MAGNITUDE; + translateData.startPos += drawP.world.drawData.cam.c.dir_from_space(moveVec); + } + selectionTransformCoords = CoordSpaceHelperTransform(translateData.startPos); } else if(transformOpHappening == TransformOperation::TRANSLATE && translateData.translateWithKeys) { - moveVec *= KEY_TRANSLATE_MAGNITUDE; - translateData.startPos += drawP.world.drawData.cam.c.dir_from_space(moveVec); - } - selectionTransformCoords = CoordSpaceHelperTransform(translateData.startPos); - } - else if(transformOpHappening == TransformOperation::TRANSLATE && translateData.translateWithKeys) { - bool anyKeyHeld = drawP.world.main.input.key(InputManager::KEY_TEXT_LEFT).held || drawP.world.main.input.key(InputManager::KEY_TEXT_RIGHT).held || drawP.world.main.input.key(InputManager::KEY_TEXT_DOWN).held || drawP.world.main.input.key(InputManager::KEY_TEXT_UP).held; - if(!anyKeyHeld) { - commit_transform_selection(); - return; + bool anyKeyHeld = drawP.world.main.input.key(InputManager::KEY_TEXT_LEFT).held || drawP.world.main.input.key(InputManager::KEY_TEXT_RIGHT).held || drawP.world.main.input.key(InputManager::KEY_TEXT_DOWN).held || drawP.world.main.input.key(InputManager::KEY_TEXT_UP).held; + if(!anyKeyHeld) { + commit_transform_selection(); + return; + } } } } diff --git a/src/DrawingProgram/Tools/LassoSelectTool.cpp b/src/DrawingProgram/Tools/LassoSelectTool.cpp index 6b0c6b1..62fa531 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.cpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.cpp @@ -57,13 +57,13 @@ void LassoSelectTool::input_key_callback(const InputManager::KeyCallbackArgs& ke void LassoSelectTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { drawP.selection.input_mouse_button_on_canvas_callback_modify_selection(button); - if(!controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && button.down && !drawP.selection.is_being_transformed()) { + if(!controls.isSelecting && button.button == InputManager::MouseButton::LEFT && button.down && !drawP.selection.is_being_transformed()) { controls = LassoSelectControls(); controls.coords = drawP.world.drawData.cam.c; controls.lassoPoints.emplace_back(controls.coords.get_mouse_pos(drawP.world)); controls.isSelecting = true; } - else if(controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && !button.down) { + else if(controls.isSelecting && button.button == InputManager::MouseButton::LEFT && !button.down) { if(controls.lassoPoints.size() > 3) { SCollision::ColliderCollection cC; diff --git a/src/DrawingProgram/Tools/LineDrawTool.cpp b/src/DrawingProgram/Tools/LineDrawTool.cpp index b975d2e..ac2897e 100644 --- a/src/DrawingProgram/Tools/LineDrawTool.cpp +++ b/src/DrawingProgram/Tools/LineDrawTool.cpp @@ -27,7 +27,7 @@ void LineDrawTool::gui_toolbox() { } void LineDrawTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { - if(button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT) { + if(button.button == InputManager::MouseButton::LEFT) { auto& toolConfig = drawP.world.main.toolConfig; if(button.down && drawP.layerMan.is_a_layer_being_edited() && !objInfoBeingEdited) { auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale); diff --git a/src/DrawingProgram/Tools/RectSelectTool.cpp b/src/DrawingProgram/Tools/RectSelectTool.cpp index 593db3d..3576fe5 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.cpp +++ b/src/DrawingProgram/Tools/RectSelectTool.cpp @@ -31,13 +31,13 @@ void RectSelectTool::input_key_callback(const InputManager::KeyCallbackArgs& key void RectSelectTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { drawP.selection.input_mouse_button_on_canvas_callback_modify_selection(button); - if(!controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && button.down && !drawP.selection.is_being_transformed()) { + if(!controls.isSelecting && button.button == InputManager::MouseButton::LEFT && button.down && !drawP.selection.is_being_transformed()) { controls = RectSelectControls(); controls.coords = drawP.world.drawData.cam.c; controls.selectStartAt = controls.selectEndAt = button.pos; controls.isSelecting = true; } - else if(controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && !button.down) { + else if(controls.isSelecting && button.button == InputManager::MouseButton::LEFT && !button.down) { using namespace SCollision; controls.selectEndAt = controls.coords.to_space(drawP.world.drawData.cam.c.from_space(button.pos)); Vector2f newP1 = drawP.world.drawData.cam.c.to_space(controls.coords.from_space(cwise_vec_min(controls.selectStartAt, controls.selectEndAt))); diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 21a3150..cdb1259 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -385,7 +385,7 @@ void InputManager::backend_mouse_button_up_update(const SDL_MouseButtonEvent& e) else if(e.button == 3) mouse.rightDown = false; main.input_mouse_button_callback(MouseButtonCallbackArgs{ - .button = static_cast(e.button), + .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, .pos = mousePos @@ -407,7 +407,7 @@ void InputManager::backend_mouse_button_down_update(const SDL_MouseButtonEvent& mouse.rightClicks = e.clicks; } main.input_mouse_button_callback(MouseButtonCallbackArgs{ - .button = static_cast(e.button), + .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, .pos = mousePos @@ -425,8 +425,15 @@ void InputManager::backend_mouse_motion_update(const SDL_MouseMotionEvent& e) { } void InputManager::backend_mouse_wheel_update(const SDL_MouseWheelEvent& e) { + Vector2f mouseNewPos = {e.mouse_x * main.window.density, e.mouse_y * main.window.density}; + mouse.set_pos(mouseNewPos); mouse.scrollAmount.x() += e.x; mouse.scrollAmount.y() += e.y; + main.input_mouse_wheel_callback({ + .mousePos = mouseNewPos, + .amount = {e.x, e.y}, + .tickAmount = {e.integer_x, e.integer_y} + }); } void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { diff --git a/src/InputManager.hpp b/src/InputManager.hpp index ed7dc2e..6cd90a0 100644 --- a/src/InputManager.hpp +++ b/src/InputManager.hpp @@ -245,12 +245,14 @@ struct InputManager { std::unordered_map defaultKeyAssignments; std::array keys; + enum class MouseButton : uint8_t { + LEFT = 1, + MIDDLE, + RIGHT + } button; + struct MouseButtonCallbackArgs { - enum class Button : uint8_t { - LEFT = 1, - MIDDLE, - RIGHT - } button; + MouseButton button; bool down; uint8_t clicks; Vector2f pos; @@ -262,7 +264,9 @@ struct InputManager { }; struct MouseWheelCallbackArgs { + Vector2f mousePos; Vector2f amount; + Vector2i tickAmount; }; MainProgram& main; diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index b4ac7c4..882f6ce 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -336,6 +336,11 @@ void MainProgram::input_mouse_motion_callback(const InputManager::MouseMotionCal world->input_mouse_motion_callback(motion); } +void MainProgram::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) { + if(world) + world->input_mouse_wheel_callback(wheel); +} + bool MainProgram::network_being_used() { for(auto& w : worlds) { if(w->netObjMan.is_connected()) diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 52ee614..9d350e4 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -123,6 +123,7 @@ class MainProgram { void input_key_callback(const InputManager::KeyCallbackArgs& key); void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); + void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel); ~MainProgram(); private: diff --git a/src/World.cpp b/src/World.cpp index 49fe2f5..d316487 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -262,17 +262,27 @@ void World::input_key_callback(const InputManager::KeyCallbackArgs& key) { } } drawProg.input_key_callback(key); + drawData.cam.input_key_callback(key); } } void World::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { - if(!clientStillConnecting) + if(!clientStillConnecting) { drawProg.input_mouse_button_callback(button); + } } void World::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { - if(!clientStillConnecting) + if(!clientStillConnecting) { drawProg.input_mouse_motion_callback(motion); + drawData.cam.input_mouse_motion_callback(*this, motion); + } +} + +void World::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) { + if(!clientStillConnecting) { + drawData.cam.input_mouse_wheel_callback(*this, wheel); + } } void World::send_chat_message(const std::string& message) { diff --git a/src/World.hpp b/src/World.hpp index bc09024..db34387 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -104,6 +104,7 @@ class World { void input_key_callback(const InputManager::KeyCallbackArgs& key); void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); + void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel); private: void load_empty_canvas(); diff --git a/src/main.cpp b/src/main.cpp index a8f15a1..84b2771 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -748,6 +748,7 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { mS.m->input.backend_mouse_button_down_update(event->button); break; case SDL_EVENT_MOUSE_WHEEL: + mS.m->update_scale_and_density(); mS.m->input.backend_mouse_wheel_update(event->wheel); break; case SDL_EVENT_KEY_DOWN: