| @@ -38,6 +38,7 @@ extern float frameRateLimit; | |||||
| extern bool frameRateSync; | extern bool frameRateSync; | ||||
| extern float autosavePeriod; | extern float autosavePeriod; | ||||
| extern bool skipLoadOnLaunch; | extern bool skipLoadOnLaunch; | ||||
| extern bool pauseUnfocused; | |||||
| extern std::string patchPath; | extern std::string patchPath; | ||||
| extern std::vector<NVGcolor> cableColors; | extern std::vector<NVGcolor> cableColors; | ||||
| @@ -64,6 +64,7 @@ struct Window { | |||||
| int frame = 0; | int frame = 0; | ||||
| /** The last known absolute mouse position in the window */ | /** The last known absolute mouse position in the window */ | ||||
| math::Vec mousePos; | math::Vec mousePos; | ||||
| bool focused; | |||||
| std::shared_ptr<Font> uiFont; | std::shared_ptr<Font> uiFont; | ||||
| double frameTimeStart = 0.f; | double frameTimeStart = 0.f; | ||||
| @@ -391,6 +391,12 @@ struct EnginePauseItem : ui::MenuItem { | |||||
| } | } | ||||
| }; | }; | ||||
| struct EnginePauseUnfocusedItem : ui::MenuItem { | |||||
| void onAction(const event::Action& e) override { | |||||
| settings::pauseUnfocused ^= true; | |||||
| } | |||||
| }; | |||||
| struct SampleRateValueItem : ui::MenuItem { | struct SampleRateValueItem : ui::MenuItem { | ||||
| float sampleRate; | float sampleRate; | ||||
| void onAction(const event::Action& e) override { | void onAction(const event::Action& e) override { | ||||
| @@ -480,6 +486,11 @@ struct EngineButton : MenuButton { | |||||
| cpuMeterItem->rightText = CHECKMARK(settings::cpuMeter); | cpuMeterItem->rightText = CHECKMARK(settings::cpuMeter); | ||||
| menu->addChild(cpuMeterItem); | menu->addChild(cpuMeterItem); | ||||
| EnginePauseUnfocusedItem* enginePauseUnfocusedItem = new EnginePauseUnfocusedItem; | |||||
| enginePauseUnfocusedItem->text = "Pause unfocused"; | |||||
| enginePauseUnfocusedItem->rightText = CHECKMARK(settings::pauseUnfocused); | |||||
| menu->addChild(enginePauseUnfocusedItem); | |||||
| SampleRateItem* sampleRateItem = new SampleRateItem; | SampleRateItem* sampleRateItem = new SampleRateItem; | ||||
| sampleRateItem->text = "Sample rate"; | sampleRateItem->text = "Sample rate"; | ||||
| sampleRateItem->rightText = RIGHT_ARROW; | sampleRateItem->rightText = RIGHT_ARROW; | ||||
| @@ -33,6 +33,7 @@ float frameRateLimit = 70.0; | |||||
| bool frameRateSync = true; | bool frameRateSync = true; | ||||
| float autosavePeriod = 15.0; | float autosavePeriod = 15.0; | ||||
| bool skipLoadOnLaunch = false; | bool skipLoadOnLaunch = false; | ||||
| bool pauseUnfocused = false; | |||||
| std::string patchPath; | std::string patchPath; | ||||
| std::vector<NVGcolor> cableColors = { | std::vector<NVGcolor> cableColors = { | ||||
| nvgRGB(0xc9, 0xb7, 0x0e), // yellow | nvgRGB(0xc9, 0xb7, 0x0e), // yellow | ||||
| @@ -64,6 +65,7 @@ json_t* toJson() { | |||||
| json_object_set_new(rootJ, "allowCursorLock", json_boolean(allowCursorLock)); | json_object_set_new(rootJ, "allowCursorLock", json_boolean(allowCursorLock)); | ||||
| json_object_set_new(rootJ, "realTime", json_boolean(realTime)); | json_object_set_new(rootJ, "realTime", json_boolean(realTime)); | ||||
| json_object_set_new(rootJ, "sampleRate", json_real(sampleRate)); | json_object_set_new(rootJ, "sampleRate", json_real(sampleRate)); | ||||
| @@ -85,6 +87,8 @@ json_t* toJson() { | |||||
| json_object_set_new(rootJ, "skipLoadOnLaunch", json_true()); | json_object_set_new(rootJ, "skipLoadOnLaunch", json_true()); | ||||
| } | } | ||||
| json_object_set_new(rootJ, "pauseUnfocused", json_boolean(pauseUnfocused)); | |||||
| json_object_set_new(rootJ, "patchPath", json_string(patchPath.c_str())); | json_object_set_new(rootJ, "patchPath", json_string(patchPath.c_str())); | ||||
| json_t* cableColorsJ = json_array(); | json_t* cableColorsJ = json_array(); | ||||
| @@ -176,6 +180,10 @@ void fromJson(json_t* rootJ) { | |||||
| if (skipLoadOnLaunchJ) | if (skipLoadOnLaunchJ) | ||||
| skipLoadOnLaunch = json_boolean_value(skipLoadOnLaunchJ); | skipLoadOnLaunch = json_boolean_value(skipLoadOnLaunchJ); | ||||
| json_t *pauseUnfocusedJ = json_object_get(rootJ, "pauseUnfocused"); | |||||
| if (pauseUnfocusedJ) | |||||
| pauseUnfocused = json_boolean_value(pauseUnfocusedJ); | |||||
| json_t* patchPathJ = json_object_get(rootJ, "patchPath"); | json_t* patchPathJ = json_object_get(rootJ, "patchPath"); | ||||
| if (patchPathJ) | if (patchPathJ) | ||||
| patchPath = json_string_value(patchPathJ); | patchPath = json_string_value(patchPathJ); | ||||
| @@ -9,6 +9,7 @@ | |||||
| #include <settings.hpp> | #include <settings.hpp> | ||||
| #include <plugin.hpp> // used in Window::screenshot | #include <plugin.hpp> // used in Window::screenshot | ||||
| #include <system.hpp> // used in Window::screenshot | #include <system.hpp> // used in Window::screenshot | ||||
| #include <engine/Engine.hpp> | |||||
| #include <map> | #include <map> | ||||
| #include <queue> | #include <queue> | ||||
| @@ -97,6 +98,14 @@ struct Window::Internal { | |||||
| bool ignoreNextMouseDelta = false; | bool ignoreNextMouseDelta = false; | ||||
| }; | }; | ||||
| static void windowFocusCallback(GLFWwindow* win, int focused) { | |||||
| Window* window = (Window*) glfwGetWindowUserPointer(win); | |||||
| window->focused = focused == GLFW_TRUE; | |||||
| if (settings::pauseUnfocused) { | |||||
| APP->engine->setPaused(!window->focused); | |||||
| } | |||||
| } | |||||
| static void windowSizeCallback(GLFWwindow* win, int width, int height) { | static void windowSizeCallback(GLFWwindow* win, int width, int height) { | ||||
| // Do nothing. Window size is reset each frame anyway. | // Do nothing. Window size is reset each frame anyway. | ||||
| @@ -252,6 +261,7 @@ Window::Window() { | |||||
| glfwSwapInterval(settings::frameRateSync ? 1 : 0); | glfwSwapInterval(settings::frameRateSync ? 1 : 0); | ||||
| // Set window callbacks | // Set window callbacks | ||||
| glfwSetWindowFocusCallback(win, windowFocusCallback); | |||||
| glfwSetWindowSizeCallback(win, windowSizeCallback); | glfwSetWindowSizeCallback(win, windowSizeCallback); | ||||
| glfwSetMouseButtonCallback(win, mouseButtonCallback); | glfwSetMouseButtonCallback(win, mouseButtonCallback); | ||||
| // Call this ourselves, but on every frame instead of only when the mouse moves | // Call this ourselves, but on every frame instead of only when the mouse moves | ||||