diff --git a/include/Helpers/CallbackManager.hpp b/include/Helpers/CallbackManager.hpp new file mode 100644 index 0000000..cadb86e --- /dev/null +++ b/include/Helpers/CallbackManager.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include + +template class CallbackManager { + public: + typedef std::function Callback; + Callback* register_callback(const Callback& func) { + Callback* toRet = new Callback(func); + funcs.emplace_back(toRet); + return toRet; + } + void deregister_callback(Callback* callbackToRemove) { + if(std::erase(funcs, callbackToRemove) > 0) + delete callbackToRemove; + } + void run_callbacks(const Args&... a) { + for(auto& f : funcs) + (*f)(a...); + } + ~CallbackManager() { + for(Callback* c : funcs) + delete c; + } + private: + std::vector funcs; +}; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index a2b164c..c4dc0d6 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -45,6 +45,87 @@ DrawingProgram::DrawingProgram(World& initWorld): drawTool = DrawingProgramToolBase::allocate_tool_type(*this, DrawingProgramToolType::BRUSH); } +void DrawingProgram::register_callbacks() { + keyCallbacks[InputManager::KEY_DRAW_TOOL_BRUSH] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_BRUSH].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::BRUSH); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_ERASER] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ERASER].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ERASER); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTSELECT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTSELECT].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::RECTSELECT); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTANGLE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTANGLE].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::RECTANGLE); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_ELLIPSE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ELLIPSE].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ELLIPSE); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_TEXTBOX] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_TEXTBOX].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::TEXTBOX); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_EYEDROPPER] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_EYEDROPPER].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::EYEDROPPER); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_SCREENSHOT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_SCREENSHOT].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::SCREENSHOT); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_ZOOM] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ZOOM].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ZOOM); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_LASSOSELECT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_LASSOSELECT].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::LASSOSELECT); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_PAN] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_PAN].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::PAN); + }); + keyCallbacks[InputManager::KEY_DRAW_TOOL_LINE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_LINE].register_callback([&](auto& key) { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::LINE); + }); + keyCallbacks[InputManager::KEY_HOLD_TO_PAN] = world.main.input.keyCallbacks[InputManager::KEY_HOLD_TO_PAN].register_callback([&](auto& key) { + if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { + toolTypeAfterTempMove = drawTool->get_type(); + switch_to_tool(DrawingProgramToolType::PAN); + tempMoveToolSwitch = TemporaryMoveToolSwitch::PAN; + } + else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::PAN) { + switch_to_tool(toolTypeAfterTempMove); + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; + } + }); + keyCallbacks[InputManager::KEY_HOLD_TO_ZOOM] = world.main.input.keyCallbacks[InputManager::KEY_HOLD_TO_ZOOM].register_callback([&](auto& key) { + if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { + toolTypeAfterTempMove = drawTool->get_type(); + switch_to_tool(DrawingProgramToolType::ZOOM); + tempMoveToolSwitch = TemporaryMoveToolSwitch::ZOOM; + } + else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::ZOOM) { + switch_to_tool(toolTypeAfterTempMove); + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; + } + }); + selection.register_key_callbacks(); +} + +void DrawingProgram::deregister_callbacks() { + for(auto& [key, callback] : keyCallbacks) + world.main.input.keyCallbacks[key].deregister_callback(callback); + keyCallbacks.clear(); + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; +} + void DrawingProgram::server_init_no_file() { layerMan.server_init_no_file(); } @@ -291,30 +372,6 @@ void DrawingProgram::update() { drag_drop_update(); - if(world.main.input.key(InputManager::KEY_DRAW_TOOL_BRUSH).pressed) - switch_to_tool(DrawingProgramToolType::BRUSH); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_ERASER).pressed) - switch_to_tool(DrawingProgramToolType::ERASER); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_RECTSELECT).pressed) - switch_to_tool(DrawingProgramToolType::RECTSELECT); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_RECTANGLE).pressed) - switch_to_tool(DrawingProgramToolType::RECTANGLE); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_ELLIPSE).pressed) - switch_to_tool(DrawingProgramToolType::ELLIPSE); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_TEXTBOX).pressed) - switch_to_tool(DrawingProgramToolType::TEXTBOX); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_EYEDROPPER).pressed) - switch_to_tool(DrawingProgramToolType::EYEDROPPER); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_SCREENSHOT).pressed) - switch_to_tool(DrawingProgramToolType::SCREENSHOT); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_ZOOM).pressed) - switch_to_tool(DrawingProgramToolType::ZOOM); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_LASSOSELECT).pressed) - switch_to_tool(DrawingProgramToolType::LASSOSELECT); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_PAN).pressed) - switch_to_tool(DrawingProgramToolType::PAN); - else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_LINE).pressed) - switch_to_tool(DrawingProgramToolType::LINE); selection.update(); drawTool->tool_update(); @@ -336,35 +393,6 @@ void DrawingProgram::update() { } void DrawingProgram::tool_temporary_switch_update() { - switch(tempMoveToolSwitch) { - case TemporaryMoveToolSwitch::NONE: - if(world.main.input.key(InputManager::KEY_HOLD_TO_PAN).held) { - toolTypeAfterTempMove = drawTool->get_type(); - switch_to_tool(DrawingProgramToolType::PAN); - tempMoveToolSwitch = TemporaryMoveToolSwitch::PAN; - } - if(world.main.input.key(InputManager::KEY_HOLD_TO_ZOOM).held) { - toolTypeAfterTempMove = drawTool->get_type(); - switch_to_tool(DrawingProgramToolType::ZOOM); - tempMoveToolSwitch = TemporaryMoveToolSwitch::ZOOM; - } - break; - case TemporaryMoveToolSwitch::PAN: { - if(!world.main.input.key(InputManager::KEY_HOLD_TO_PAN).held) { - switch_to_tool(toolTypeAfterTempMove); - tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; - } - break; - } - case TemporaryMoveToolSwitch::ZOOM: { - if(!world.main.input.key(InputManager::KEY_HOLD_TO_ZOOM).held) { - switch_to_tool(toolTypeAfterTempMove); - tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; - } - break; - } - } - if(world.main.input.pen.isEraser && !temporaryEraser && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { if(drawTool->get_type() == DrawingProgramToolType::BRUSH) switch_to_tool(DrawingProgramToolType::ERASER); diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index 439c87c..ce994b5 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -56,6 +56,10 @@ class DrawingProgram { void invalidate_cache_at_component(CanvasComponentContainer::ObjInfo* objToCheck); void preupdate_component(CanvasComponentContainer::ObjInfo* objToCheck); void send_transforms_for(const std::vector& objsToSendTransformsFor); + + void register_callbacks(); + void deregister_callbacks(); + private: void process_transform_message(const std::vector>& transforms); @@ -121,6 +125,8 @@ class DrawingProgram { uint32_t nextID = 0; + std::unordered_map keyCallbacks; + friend class EyeDropperTool; friend class RectDrawTool; friend class EllipseDrawTool; diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 9d9bc13..00e50d7 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -494,32 +494,44 @@ void DrawingProgramSelection::update() { commit_transform_selection(); return; } + } +} - if(drawP.world.main.input.key(InputManager::KEY_GENERIC_ESCAPE).pressed) - deselect_all(); - else if(drawP.world.main.input.key(InputManager::KEY_DRAW_DELETE).pressed) +void DrawingProgramSelection::register_key_callbacks() { + drawP.keyCallbacks[InputManager::KEY_DRAW_DELETE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_DRAW_DELETE].register_callback([&](auto& key) { + if(key.down && !key.repeat) delete_all(); - else if(drawP.world.main.input.key(InputManager::KEY_COPY).pressed && !is_being_transformed()) + }); + drawP.keyCallbacks[InputManager::KEY_COPY] = drawP.world.main.input.keyCallbacks[InputManager::KEY_COPY].register_callback([&](auto& key) { + if(key.down && !key.repeat) selection_to_clipboard(); - else if(drawP.world.main.input.key(InputManager::KEY_CUT).pressed && !is_being_transformed()) { + }); + drawP.keyCallbacks[InputManager::KEY_CUT] = drawP.world.main.input.keyCallbacks[InputManager::KEY_CUT].register_callback([&](auto& key) { + if(key.down && !key.repeat) { selection_to_clipboard(); delete_all(); } - else if(drawP.world.main.input.key(InputManager::KEY_PASTE).pressed) { + }); + drawP.keyCallbacks[InputManager::KEY_PASTE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_PASTE].register_callback([&](auto& key) { + if(key.down && !key.repeat) { deselect_all(); paste_clipboard(drawP.world.main.input.mouse.pos); } - else if(drawP.world.main.input.key(InputManager::KEY_PASTE_IMAGE).pressed) { + }); + drawP.keyCallbacks[InputManager::KEY_PASTE_IMAGE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_PASTE_IMAGE].register_callback([&](auto& key) { + if(key.down && !key.repeat) { deselect_all(); paste_image(drawP.world.main.input.mouse.pos); } - } - else if(drawP.world.main.input.key(InputManager::KEY_PASTE).pressed && !drawP.prevent_undo_or_redo()) - paste_clipboard(drawP.world.main.input.mouse.pos); - else if(drawP.world.main.input.key(InputManager::KEY_PASTE_IMAGE).pressed && !drawP.prevent_undo_or_redo()) - paste_image(drawP.world.main.input.mouse.pos); - else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_ESCAPE).pressed) - drawP.switch_to_tool(DrawingProgramToolType::EDIT, true); + }); + drawP.keyCallbacks[InputManager::KEY_DESELECT_AND_EDIT_TOOL] = drawP.world.main.input.keyCallbacks[InputManager::KEY_DESELECT_AND_EDIT_TOOL].register_callback([&](auto& key) { + if(key.down && !key.repeat) { + if(is_something_selected()) + deselect_all(); + else + drawP.switch_to_tool(DrawingProgramToolType::EDIT, true); + } + }); } void DrawingProgramSelection::deselect_all() { @@ -580,16 +592,18 @@ CanvasComponentContainer::ObjInfo* DrawingProgramSelection::get_front_object_col void DrawingProgramSelection::selection_to_clipboard() { check_add_stroke_color_change_undo(); - auto& clipboard = drawP.world.main.clipboard; - std::unordered_set resourceSet; - for(auto& c : selectedSet) - c->obj->get_comp().get_used_resources(resourceSet); - clipboard.components.clear(); - for(auto& c : selectedSet) - clipboard.components.emplace_back(c->obj->get_data_copy()); - clipboard.pos = initialSelectionAABB.center(); - clipboard.inverseScale = drawP.world.drawData.cam.c.inverseScale; - clipboard.resources = drawP.world.rMan.copy_resource_set_to_map(resourceSet); + if(is_something_selected()) { + auto& clipboard = drawP.world.main.clipboard; + std::unordered_set resourceSet; + for(auto& c : selectedSet) + c->obj->get_comp().get_used_resources(resourceSet); + clipboard.components.clear(); + for(auto& c : selectedSet) + clipboard.components.emplace_back(c->obj->get_data_copy()); + clipboard.pos = initialSelectionAABB.center(); + clipboard.inverseScale = drawP.world.drawData.cam.c.inverseScale; + clipboard.resources = drawP.world.rMan.copy_resource_set_to_map(resourceSet); + } } void DrawingProgramSelection::paste_clipboard(Vector2f pasteScreenPos) { diff --git a/src/DrawingProgram/DrawingProgramSelection.hpp b/src/DrawingProgram/DrawingProgramSelection.hpp index 4379283..c00a356 100644 --- a/src/DrawingProgram/DrawingProgramSelection.hpp +++ b/src/DrawingProgram/DrawingProgramSelection.hpp @@ -28,6 +28,7 @@ class DrawingProgramSelection { void delete_all(); void selection_to_clipboard(); CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection& cC); + void register_key_callbacks(); private: bool mouse_collided_with_selection_aabb(); bool mouse_collided_with_scale_point(); diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 318fae3..e30ba6d 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -58,6 +58,7 @@ InputManager::InputManager() { defaultKeyAssignments[{0, SDLK_F2}] = KEY_SHOW_PLAYER_LIST; defaultKeyAssignments[{0, SDLK_SPACE}] = KEY_HOLD_TO_PAN; defaultKeyAssignments[{0, SDLK_Z}] = KEY_HOLD_TO_ZOOM; + defaultKeyAssignments[{0, SDLK_ESCAPE}] = KEY_DESELECT_AND_EDIT_TOOL; #ifdef __EMSCRIPTEN__ // Without this, SDL eats the CTRL-V event that initiates the paste event @@ -355,9 +356,11 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { // e.key != SDLK_LMETA && e.key != SDLK_RMETA && - if(stopKeyInput) + if(stopKeyInput && !e.down) return; + sdlKeyCallbacks.run_callbacks(e); + switch(kPress) { case SDLK_UP: set_key_down(e, KEY_TEXT_UP); @@ -482,12 +485,14 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { break; } - if(text.get_accepting_input()) + if(text.get_accepting_input() && e.down) return; auto f = keyAssignments.find({make_generic_key_mod(kMod), kPress}); - if(f != keyAssignments.end()) + if(f != keyAssignments.end()) { set_key_down(e, f->second); + keyCallbacks[f->second].run_callbacks(KeyCallbackArgs{.down = e.down, .repeat = e.repeat}); + } } void InputManager::call_text_paste(bool isRichTextPaste) { diff --git a/src/InputManager.hpp b/src/InputManager.hpp index 18c42b1..fa8abd0 100644 --- a/src/InputManager.hpp +++ b/src/InputManager.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "UndoManager.hpp" #include @@ -173,6 +174,7 @@ struct InputManager { KEY_SHOW_PLAYER_LIST, KEY_HOLD_TO_PAN, KEY_HOLD_TO_ZOOM, + KEY_DESELECT_AND_EDIT_TOOL, KEY_ASSIGNABLE_COUNT, // Not a real key @@ -231,6 +233,15 @@ struct InputManager { const KeyData& key(KeyCode kCode); + CallbackManager sdlKeyCallbacks; + + struct KeyCallbackArgs { + bool down; + bool repeat; + }; + typedef CallbackManager KeyCallbackManager; + std::array keyCallbacks; + std::unordered_map keyAssignments; std::unordered_map defaultKeyAssignments; std::array keys; @@ -266,5 +277,6 @@ NLOHMANN_JSON_SERIALIZE_ENUM(InputManager::KeyCodeEnum, { {InputManager::KEY_OPEN_CHAT, "Open Chat"}, {InputManager::KEY_SHOW_PLAYER_LIST, "Show Player List"}, {InputManager::KEY_HOLD_TO_PAN, "Hold to Pan"}, - {InputManager::KEY_HOLD_TO_ZOOM, "Hold to Zoom"} + {InputManager::KEY_HOLD_TO_ZOOM, "Hold to Zoom"}, + {InputManager::KEY_DESELECT_AND_EDIT_TOOL, "Deselect selection / Edit Tool"} }) diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index 4992cae..5a2776a 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -61,6 +61,19 @@ MainProgram::MainProgram(): *logFile << "[CHAT] " << text << std::endl; std::cout << "[CHAT] " << text << std::endl; }); + + register_callbacks(); +} + +void MainProgram::register_callbacks() { + input.keyCallbacks[InputManager::KEY_NOGUI].register_callback([&](auto& keyData) { + if(keyData.down && !keyData.repeat) + drawGui = !drawGui; + }); + input.keyCallbacks[InputManager::KEY_FULLSCREEN].register_callback([&](auto& keyData) { + if(keyData.down && !keyData.repeat) + drawGui = !drawGui; + }); } void MainProgram::update() { @@ -97,8 +110,12 @@ void MainProgram::update() { std::shared_ptr oldWorld = world; world = worlds[worldIndex]; - if(oldWorld != world && oldWorld) - oldWorld->on_switch_out(); + if(oldWorld != world) { + if(oldWorld) + oldWorld->on_tab_out(); + if(world) + world->on_tab_in(); + } deltaTime.update_time_since(); deltaTime.update_time_point(); @@ -114,11 +131,6 @@ void MainProgram::update() { toolbar.update(); // GUI should be setup after the world data has been fully updated for this frame, so that the GUI reflects the current state of the world data - if(input.key(InputManager::KEY_NOGUI).pressed) - drawGui = !drawGui; - - if(input.key(InputManager::KEY_FULLSCREEN).pressed) - input.toggleFullscreen = true; NetLibrary::update(); diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 45a2817..2bf0ecb 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -122,6 +122,7 @@ class MainProgram { ~MainProgram(); private: + void register_callbacks(); void new_tab_open(); std::atomic tabSetToOpen = false; World::OpenWorldInfo newTabToOpenInfo; diff --git a/src/World.cpp b/src/World.cpp index 4c15b0a..e76d3e6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -151,6 +151,9 @@ void World::init_client(const std::string& serverFullID) { #endif clientStillConnecting = false; + + if(is_focus()) + register_callbacks(); }); netClient->add_recv_callback(CLIENT_UPDATE_NETWORK_OBJECT, [&](cereal::PortableBinaryInputArchive& message) { netObjMan.read_update_message(message, nullptr); @@ -191,11 +194,6 @@ void World::focus_update() { drawData.cam.update_main(*this); rMan.update(); - - if(main.input.key(InputManager::KEY_UNDO).repeat) - undo_with_checks(); - else if(main.input.key(InputManager::KEY_REDO).repeat) - redo_with_checks(); } void World::connection_update() { @@ -228,6 +226,10 @@ void World::connection_update() { } } +bool World::is_focus() { + return main.world.get() == this; +} + void World::undo_with_checks() { if(!clientStillConnecting && !drawProg.prevent_undo_or_redo()) undo.undo(); @@ -244,8 +246,33 @@ void World::unfocus_update() { return; } -void World::on_switch_out() { +void World::on_tab_out() { rMan.clear_display_cache(); + if(!clientStillConnecting) + deregister_callbacks(); +} + +void World::on_tab_in() { + if(!clientStillConnecting) + register_callbacks(); +} + +void World::register_callbacks() { + drawProg.register_callbacks(); + redoKeyCallback = main.input.keyCallbacks[InputManager::KEY_REDO].register_callback([&](auto& key) { + if(key.down && !key.repeat) + redo_with_checks(); + }); + undoKeyCallback = main.input.keyCallbacks[InputManager::KEY_UNDO].register_callback([&](auto& key) { + if(key.down && !key.repeat) + undo_with_checks(); + }); +} + +void World::deregister_callbacks() { + drawProg.deregister_callbacks(); + main.input.keyCallbacks[InputManager::KEY_REDO].deregister_callback(redoKeyCallback); + main.input.keyCallbacks[InputManager::KEY_UNDO].deregister_callback(undoKeyCallback); } void World::send_chat_message(const std::string& message) { diff --git a/src/World.hpp b/src/World.hpp index c59c267..1c5e584 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -66,7 +66,8 @@ class World { void focus_update(); void unfocus_update(); - void on_switch_out(); + void on_tab_out(); + void on_tab_in(); void draw(SkCanvas* canvas, const DrawData& calledDrawData); void early_destroy(); @@ -92,6 +93,7 @@ class World { void scale_up_step(); bool should_ask_before_closing(); + bool is_focus(); bool hasUnsavedLocalChanges = false; bool setToDestroy = false; @@ -100,6 +102,11 @@ class World { std::shared_ptr netServer; std::shared_ptr netClient; private: + InputManager::KeyCallbackManager::Callback* undoKeyCallback; + InputManager::KeyCallbackManager::Callback* redoKeyCallback; + void register_callbacks(); + void deregister_callbacks(); + void load_empty_canvas(); Vector3f get_random_cursor_color();