Skip to content

Commit d687984

Browse files
committed
All keys working in editor play
1 parent 77b3a89 commit d687984

2 files changed

Lines changed: 106 additions & 29 deletions

File tree

editor/window/SceneWindow.cpp

Lines changed: 98 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ bool editor::SceneWindow::isFocused() const {
7171
}
7272

7373
void editor::SceneWindow::resetProjectState() {
74+
releasePlayKeys(0);
7475
windowFocused = false;
7576
mouseLeftDown = false;
7677
mouseLeftDraggedInside = false;
@@ -84,6 +85,9 @@ void editor::SceneWindow::resetProjectState() {
8485
}
8586

8687
void editor::SceneWindow::clearSceneState(uint32_t sceneId) {
88+
if (sceneId == playKeysSceneId) {
89+
releasePlayKeys(0);
90+
}
8791
draggingMouse.erase(sceneId);
8892
suppressLeftMouseUntilRelease.erase(sceneId);
8993
walkSpeed.erase(sceneId);
@@ -539,17 +543,20 @@ void editor::SceneWindow::forwardPlayKeyboardInput(ImGuiIO& io, int mods){
539543
Engine::systemCharInput(charInput);
540544
}
541545
Engine::systemKeyDown(engineKey, false, mods);
546+
playPressedKeys.insert(engineKey);
542547
}else if (allowRepeat && ImGui::IsKeyPressed(imguiKey, true)){
543548
if (charInput != 0){
544549
Engine::systemCharInput(charInput);
545550
}
546551
Engine::systemKeyDown(engineKey, true, mods);
552+
playPressedKeys.insert(engineKey);
547553
}
548554
};
549555

550556
auto forwardKeyRelease = [&](ImGuiKey imguiKey, int engineKey){
551557
if (ImGui::IsKeyReleased(imguiKey)){
552558
Engine::systemKeyUp(engineKey, false, mods);
559+
playPressedKeys.erase(engineKey);
553560
}
554561
};
555562

@@ -558,29 +565,75 @@ void editor::SceneWindow::forwardPlayKeyboardInput(ImGuiIO& io, int mods){
558565
forwardKeyRelease(imguiKey, engineKey);
559566
};
560567

568+
auto forwardKeyRange = [&](ImGuiKey imguiFirst, int engineFirst, int count){
569+
for (int i = 0; i < count; i++){
570+
forwardKey(static_cast<ImGuiKey>(static_cast<int>(imguiFirst) + i), engineFirst + i);
571+
}
572+
};
573+
561574
forwardKey(ImGuiKey_Tab, D_KEY_TAB, L'\t', false);
562575
forwardKey(ImGuiKey_Backspace, D_KEY_BACKSPACE, L'\b');
563576
forwardKey(ImGuiKey_Enter, D_KEY_ENTER, L'\r', false);
564-
forwardKey(ImGuiKey_KeypadEnter, D_KEY_ENTER, L'\r', false);
577+
forwardKey(ImGuiKey_KeypadEnter, D_KEY_KP_ENTER, L'\r', false);
565578
forwardKey(ImGuiKey_Escape, D_KEY_ESCAPE, L'\e', false);
566579
forwardKey(ImGuiKey_Space, D_KEY_SPACE);
567580
forwardKey(ImGuiKey_LeftArrow, D_KEY_LEFT);
568581
forwardKey(ImGuiKey_RightArrow, D_KEY_RIGHT);
569582
forwardKey(ImGuiKey_UpArrow, D_KEY_UP);
570583
forwardKey(ImGuiKey_DownArrow, D_KEY_DOWN);
584+
forwardKey(ImGuiKey_Insert, D_KEY_INSERT, 0, false);
571585
forwardKey(ImGuiKey_Home, D_KEY_HOME, 0, false);
572586
forwardKey(ImGuiKey_End, D_KEY_END, 0, false);
587+
forwardKey(ImGuiKey_PageUp, D_KEY_PAGE_UP);
588+
forwardKey(ImGuiKey_PageDown, D_KEY_PAGE_DOWN);
573589
forwardKey(ImGuiKey_Delete, D_KEY_DELETE);
574590

575-
for (int i = 0; i < 10; i++){
576-
ImGuiKey imguiKey = static_cast<ImGuiKey>(static_cast<int>(ImGuiKey_0) + i);
577-
forwardKey(imguiKey, D_KEY_0 + i);
578-
}
591+
forwardKey(ImGuiKey_Apostrophe, D_KEY_APOSTROPHE);
592+
forwardKey(ImGuiKey_Comma, D_KEY_COMMA);
593+
forwardKey(ImGuiKey_Minus, D_KEY_MINUS);
594+
forwardKey(ImGuiKey_Period, D_KEY_PERIOD);
595+
forwardKey(ImGuiKey_Slash, D_KEY_SLASH);
596+
forwardKey(ImGuiKey_Semicolon, D_KEY_SEMICOLON);
597+
forwardKey(ImGuiKey_Equal, D_KEY_EQUAL);
598+
forwardKey(ImGuiKey_LeftBracket, D_KEY_LEFT_BRACKET);
599+
forwardKey(ImGuiKey_Backslash, D_KEY_BACKSLASH);
600+
forwardKey(ImGuiKey_RightBracket, D_KEY_RIGHT_BRACKET);
601+
forwardKey(ImGuiKey_GraveAccent, D_KEY_GRAVE_ACCENT);
602+
603+
forwardKey(ImGuiKey_CapsLock, D_KEY_CAPS_LOCK, 0, false);
604+
forwardKey(ImGuiKey_ScrollLock, D_KEY_SCROLL_LOCK, 0, false);
605+
forwardKey(ImGuiKey_NumLock, D_KEY_NUM_LOCK, 0, false);
606+
forwardKey(ImGuiKey_PrintScreen, D_KEY_PRINT_SCREEN, 0, false);
607+
forwardKey(ImGuiKey_Pause, D_KEY_PAUSE, 0, false);
608+
609+
forwardKey(ImGuiKey_LeftShift, D_KEY_LEFT_SHIFT, 0, false);
610+
forwardKey(ImGuiKey_LeftCtrl, D_KEY_LEFT_CONTROL, 0, false);
611+
forwardKey(ImGuiKey_LeftAlt, D_KEY_LEFT_ALT, 0, false);
612+
forwardKey(ImGuiKey_LeftSuper, D_KEY_LEFT_SUPER, 0, false);
613+
forwardKey(ImGuiKey_RightShift, D_KEY_RIGHT_SHIFT, 0, false);
614+
forwardKey(ImGuiKey_RightCtrl, D_KEY_RIGHT_CONTROL, 0, false);
615+
forwardKey(ImGuiKey_RightAlt, D_KEY_RIGHT_ALT, 0, false);
616+
forwardKey(ImGuiKey_RightSuper, D_KEY_RIGHT_SUPER, 0, false);
617+
forwardKey(ImGuiKey_Menu, D_KEY_MENU, 0, false);
618+
619+
forwardKeyRange(ImGuiKey_0, D_KEY_0, 10);
620+
forwardKeyRange(ImGuiKey_A, D_KEY_A, 26);
621+
forwardKeyRange(ImGuiKey_F1, D_KEY_F1, 24);
622+
forwardKeyRange(ImGuiKey_Keypad0, D_KEY_KP_0, 10);
623+
624+
forwardKey(ImGuiKey_KeypadDecimal, D_KEY_KP_DECIMAL);
625+
forwardKey(ImGuiKey_KeypadDivide, D_KEY_KP_DIVIDE);
626+
forwardKey(ImGuiKey_KeypadMultiply, D_KEY_KP_MULTIPLY);
627+
forwardKey(ImGuiKey_KeypadSubtract, D_KEY_KP_SUBTRACT);
628+
forwardKey(ImGuiKey_KeypadAdd, D_KEY_KP_ADD);
629+
forwardKey(ImGuiKey_KeypadEqual, D_KEY_KP_EQUAL);
630+
}
579631

580-
for (int i = 0; i < 26; i++){
581-
ImGuiKey imguiKey = static_cast<ImGuiKey>(static_cast<int>(ImGuiKey_A) + i);
582-
forwardKey(imguiKey, D_KEY_A + i);
632+
void editor::SceneWindow::releasePlayKeys(int mods){
633+
for (int key : playPressedKeys){
634+
Engine::systemKeyUp(key, false, mods);
583635
}
636+
playPressedKeys.clear();
584637
}
585638

586639
void editor::SceneWindow::sceneEventHandler(SceneProject* sceneProject) {
@@ -600,34 +653,50 @@ void editor::SceneWindow::sceneEventHandler(SceneProject* sceneProject) {
600653
bool isMouseInWindow = ImGui::IsWindowHovered() && (mousePos.x >= windowPos.x && mousePos.x <= windowPos.x + windowSize.x &&
601654
mousePos.y >= windowPos.y && mousePos.y <= windowPos.y + windowSize.y);
602655

603-
// When scene is playing, forward mouse events to Engine
604-
if (sceneProject->playState == ScenePlayState::PLAYING && isMouseInWindow) {
605-
float x = mousePos.x - windowPos.x;
606-
float y = mousePos.y - windowPos.y;
656+
int mods = 0;
657+
if (io.KeyShift) mods |= D_MODIFIER_SHIFT;
658+
if (io.KeyCtrl) mods |= D_MODIFIER_CONTROL;
659+
if (io.KeyAlt) mods |= D_MODIFIER_ALT;
660+
if (io.KeySuper) mods |= D_MODIFIER_SUPER;
607661

608-
int mods = 0;
609-
if (io.KeyShift) mods |= D_MODIFIER_SHIFT;
610-
if (io.KeyCtrl) mods |= D_MODIFIER_CONTROL;
611-
if (io.KeyAlt) mods |= D_MODIFIER_ALT;
612-
if (io.KeySuper) mods |= D_MODIFIER_SUPER;
662+
// When scene is playing, forward mouse and keyboard events to Engine
663+
if (sceneProject->playState == ScenePlayState::PLAYING) {
664+
if (isMouseInWindow) {
665+
float x = mousePos.x - windowPos.x;
666+
float y = mousePos.y - windowPos.y;
613667

614-
Engine::systemMouseMove(x, y, mods);
668+
Engine::systemMouseMove(x, y, mods);
615669

616-
if (mouseWheel != 0) {
617-
Engine::systemMouseScroll(0, mouseWheel, mods);
618-
}
619-
620-
for (int i = 0; i < 5; i++) {
621-
if (ImGui::IsMouseClicked(i)) {
622-
Engine::systemMouseDown(i, x, y, mods);
670+
if (mouseWheel != 0) {
671+
Engine::systemMouseScroll(0, mouseWheel, mods);
623672
}
624-
if (ImGui::IsMouseReleased(i)) {
625-
Engine::systemMouseUp(i, x, y, mods);
673+
674+
for (int i = 0; i < 5; i++) {
675+
if (ImGui::IsMouseClicked(i)) {
676+
Engine::systemMouseDown(i, x, y, mods);
677+
}
678+
if (ImGui::IsMouseReleased(i)) {
679+
Engine::systemMouseUp(i, x, y, mods);
680+
}
626681
}
627682
}
628683

629-
forwardPlayKeyboardInput(io, mods);
630-
return;
684+
// Keyboard follows window focus, not mouse hover, so held keys keep
685+
// working while the mouse drifts out of the window. On focus loss the
686+
// key-up events would never arrive, so release held keys explicitly.
687+
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) {
688+
playKeysSceneId = sceneProject->id;
689+
forwardPlayKeyboardInput(io, mods);
690+
} else if (playKeysSceneId == sceneProject->id) {
691+
releasePlayKeys(mods);
692+
}
693+
694+
if (isMouseInWindow) {
695+
return;
696+
}
697+
} else if (playKeysSceneId == sceneProject->id) {
698+
// Play stopped or paused with keys still held
699+
releasePlayKeys(mods);
631700
}
632701

633702
size_t sceneId = sceneProject->id;

editor/window/SceneWindow.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "command/type/PropertyCmd.h"
1010
#include "render/gizmo/ViewportGizmo.h"
1111
#include <unordered_map>
12+
#include <set>
1213

1314
namespace doriax::editor {
1415

@@ -35,6 +36,12 @@ namespace doriax::editor {
3536
std::map<uint32_t, bool> suppressLeftMouseUntilRelease;
3637
std::map<uint32_t, float> walkSpeed;
3738

39+
// Engine keys sent down during play but not yet released, and the
40+
// scene the play session belongs to. Engine Input state is static,
41+
// so a missed key-up would stay pressed into the next play session.
42+
std::set<int> playPressedKeys;
43+
uint32_t playKeysSceneId = 0;
44+
3845
std::map<uint32_t, int> width;
3946
std::map<uint32_t, int> height;
4047

@@ -46,6 +53,7 @@ namespace doriax::editor {
4653
void closeSceneInternal(uint32_t sceneId);
4754
void sceneEventHandler(SceneProject* sceneProject);
4855
void forwardPlayKeyboardInput(ImGuiIO& io, int mods);
56+
void releasePlayKeys(int mods);
4957
void handleResourceFileDragDrop(SceneProject* sceneProject);
5058
Vector3 getModelDropPosition(SceneProject* sceneProject, float x, float y, Entity hitEntity);
5159
void handleTileRectDragDrop(SceneProject* sceneProject);

0 commit comments

Comments
 (0)