diff --git a/res/icons/LICENSE_settings_icon.txt b/res/icons/LICENSE_settings_icon.txt new file mode 100644 index 00000000..87e156fe --- /dev/null +++ b/res/icons/LICENSE_settings_icon.txt @@ -0,0 +1 @@ +
Icons made by Egor Rumyantsev from www.flaticon.com is licensed by CC 3.0 BY
diff --git a/res/icons/settings_icon_cc.svg b/res/icons/settings_icon_cc.svg new file mode 100644 index 00000000..3637457e --- /dev/null +++ b/res/icons/settings_icon_cc.svg @@ -0,0 +1,78 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/icons/settings_icon_cc__ORIG.svg b/res/icons/settings_icon_cc__ORIG.svg new file mode 100644 index 00000000..79253bf7 --- /dev/null +++ b/res/icons/settings_icon_cc__ORIG.svg @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/src/app/Toolbar.cpp b/src/app/Toolbar.cpp index ff43d2c3..33c174b4 100644 --- a/src/app/Toolbar.cpp +++ b/src/app/Toolbar.cpp @@ -3,6 +3,7 @@ #include "window.hpp" #include "engine.hpp" #include "asset.hpp" +#include "settings.hpp" #include "global.hpp" #include "global_ui.hpp" @@ -14,6 +15,9 @@ extern void vst2_oversample_channels_set (int _numIn, int _numOut); extern void vst2_oversample_channels_get (int *_numIn, int *_numOut); extern void vst2_idle_detect_mode_set (int _mode); extern void vst2_idle_detect_mode_get (int *_mode); +extern void vst2_refresh_rate_set (float _hz); +extern float vst2_refresh_rate_get (void); +extern void vst2_window_size_set (int _width, int _height); #endif // RACK_HOST namespace rack { @@ -320,6 +324,125 @@ struct IdleModeButton : TooltipIconButton { } }; +struct settings_win_size_entry_t { + int w; + int h; +}; + +static settings_win_size_entry_t loc_settings_win_sizes[] = { + { 1002, 600 }, + { 1272, 820 }, + { 1408, 850 }, + { 1588, 1100 }, + { 1902, 1100 }, + { 2500, 1980 }, + { 3000, 1980 }, +}; +#define NUM_SETTINGS_WIN_SIZE (sizeof(loc_settings_win_sizes) / sizeof(settings_win_size_entry_t)) + +struct SettingsWinSizeItem : MenuItem { + const settings_win_size_entry_t *setting; + + void onAction(EventAction &e) override { +#ifdef RACK_HOST + global_ui->window.windowWidth = setting->w; + global_ui->window.windowHeight = setting->h; + vst2_window_size_set(setting->w, setting->h); +#endif // RACK_HOST + } +}; + +struct settings_refresh_rate_entry_t { + int rate; + const char *caption; +}; + +static settings_refresh_rate_entry_t loc_settings_refresh_rates[] = { + { 0, "" }, + { 15, "15 fps" }, + { 30, "30 fps" }, + { 60, "60 fps" }, + { 75, "75 fps" }, + { 100, "100 fps" }, +}; +#define NUM_SETTINGS_REFRESH_RATE (sizeof(loc_settings_refresh_rates) / sizeof(settings_refresh_rate_entry_t)) + +struct SettingsRefreshRateItem : MenuItem { + const settings_refresh_rate_entry_t *setting; + + void onAction(EventAction &e) override { +#ifdef RACK_HOST + vst2_refresh_rate_set(float(setting->rate)); +#endif // RACK_HOST + } +}; + +struct SettingsVsyncItem : MenuItem { + + void onAction(EventAction &e) override { + lglw_swap_interval_set(global_ui->window.lglw, lglw_swap_interval_get(global_ui->window.lglw) ^ 1); + } +}; + +struct SettingsSaveItem : MenuItem { + + void onAction(EventAction &e) override { + settingsSave(assetLocal("settings.json")); + } +}; + +struct SettingsButton : TooltipIconButton { + SettingsButton() { + setSVG(SVG::load(assetGlobal("res/icons/settings_icon_cc.svg"))); + tooltipText = "Global Settings"; + } + void onAction(EventAction &e) override { + Menu *menu = global_ui->ui.gScene->createMenu(); + menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)); + menu->box.size.x = box.size.x; + + menu->addChild(MenuLabel::create("Global Settings")); + +#ifdef RACK_HOST + int cWinW = int(global_ui->window.windowWidth); + int cWinH = int(global_ui->window.windowHeight); + for(int i = 0; i < NUM_SETTINGS_WIN_SIZE; i++) + { + const settings_win_size_entry_t *en = &loc_settings_win_sizes[i]; + + SettingsWinSizeItem *winSizeItem = new SettingsWinSizeItem(); + char buf[256]; + sprintf(buf, "%dx%d", en->w, en->h); + winSizeItem->text = buf; + winSizeItem->setting = en; + winSizeItem->rightText = CHECKMARK( (cWinW == en->w) && (cWinH == en->h) ); + menu->addChild(winSizeItem); + } + + int cRate = int(vst2_refresh_rate_get()); + for(int i = 0; i < NUM_SETTINGS_REFRESH_RATE; i++) + { + const settings_refresh_rate_entry_t *en = &loc_settings_refresh_rates[i]; + + SettingsRefreshRateItem *rateItem = new SettingsRefreshRateItem(); + rateItem->text = en->caption; + rateItem->setting = en; + rateItem->rightText = CHECKMARK( (cRate == en->rate) ); + menu->addChild(rateItem); + } + + SettingsVsyncItem *vsyncItem = new SettingsVsyncItem(); + vsyncItem->text = "Vsync"; + vsyncItem->rightText = CHECKMARK( (0 != lglw_swap_interval_get(global_ui->window.lglw)) ); + menu->addChild(vsyncItem); + + SettingsSaveItem *saveItem = new SettingsSaveItem(); + saveItem->text = "Save Settings (+Favourites)"; + menu->addChild(saveItem); +#endif // RACK_HOST + } +}; + struct ZoomSlider : Slider { void onAction(EventAction &e) override { Slider::onAction(e); @@ -347,6 +470,7 @@ Toolbar::Toolbar() { layout->addChild(new PowerMeterButton()); layout->addChild(new RackLockButton()); layout->addChild(new IdleModeButton()); + layout->addChild(new SettingsButton()); wireOpacitySlider = new Slider(); wireOpacitySlider->box.size.x = 150; diff --git a/src/settings.cpp b/src/settings.cpp index 802147bb..41c6ad62 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -9,16 +9,22 @@ #include "global_ui.hpp" +#ifdef RACK_HOST extern void vst2_window_size_set (int _width, int _height); extern void vst2_refresh_rate_set (float _hz); - -#ifdef RACK_HOST +extern float vst2_refresh_rate_get (void); extern void vst2_oversample_realtime_set (float _factor, int _quality); +extern void vst2_oversample_realtime_get (float *_factor, int *_quality); extern void vst2_oversample_offline_set (float _factor, int _quality); +extern void vst2_oversample_offline_get (float *_factor, int *_quality); extern void vst2_oversample_offline_check_set (int _bEnable); +extern int32_t vst2_oversample_offline_check_get (void); extern void vst2_oversample_channels_set (int _numIn, int _numOut); +extern void vst2_oversample_channels_get (int *_numIn, int *_numOut); extern void vst2_idle_detect_mode_fx_set (int _mode); +extern int vst2_idle_detect_mode_fx_get (void); extern void vst2_idle_detect_mode_instr_set (int _mode); +extern int vst2_idle_detect_mode_instr_get (void); #endif // RACK_HOST namespace rack { @@ -30,11 +36,16 @@ static json_t *settingsToJson() { // root json_t *rootJ = json_object(); +#ifdef RACK_HOST + // token json_t *tokenJ = json_string(global->plugin.gToken.c_str()); json_object_set_new(rootJ, "token", tokenJ); - if (!windowIsMaximized()) { +#if 0 + if (!windowIsMaximized()) +#endif + { // windowSize Vec windowSize = windowGetWindowSize(); json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y); @@ -61,6 +72,86 @@ static json_t *settingsToJson() { json_t *zoomJ = json_real(zoom); json_object_set_new(rootJ, "zoom", zoomJ); + // refresh rate (Hz) + float refreshRate = vst2_refresh_rate_get(); + json_t *refreshRateJ = json_integer(int(refreshRate)); + json_object_set_new(rootJ, "refreshRate", refreshRateJ); + + // vsync + int vsync = lglw_swap_interval_get(global_ui->window.lglw); + json_t *vsyncJ = json_boolean(vsync); + json_object_set_new(rootJ, "vsync", vsyncJ); + + // touchInput + int touchInput = lglw_touchinput_get(global_ui->window.lglw); + json_t *touchInputJ = json_boolean(touchInput); + json_object_set_new(rootJ, "touchInput", touchInputJ); + + // touchKbd + int touchKbd = b_touchkeyboard_enable; + json_t *touchKbdJ = json_boolean(touchKbd); + json_object_set_new(rootJ, "touchKbd", touchKbdJ); + + // (realtime) oversampleFactor, oversampleQuality + { + float factor; + int quality; + vst2_oversample_realtime_get(&factor, &quality); + + json_t *factorJ = json_real(factor); + json_object_set_new(rootJ, "oversampleFactor", factorJ); + + json_t *qualityJ = json_integer(quality); + json_object_set_new(rootJ, "oversampleQuality", qualityJ); + } + + // oversampleOfflineFactor, oversampleOfflineQuality + { + float factor; + int quality; + vst2_oversample_offline_get(&factor, &quality); + + json_t *factorJ = json_real(factor); + json_object_set_new(rootJ, "oversampleOfflineFactor", factorJ); + + json_t *qualityJ = json_integer(quality); + json_object_set_new(rootJ, "oversampleOfflineQuality", qualityJ); + } + + // oversample offline check (oversampleOffline) + json_t *offlineJ = json_boolean(vst2_oversample_offline_check_get()); + json_object_set_new(rootJ, "oversampleOffline", offlineJ); + + // oversample input channel limit (oversampleNumIn) + // oversample output channel limit (oversampleNumOut) + { + int numIn; + int numOut; + vst2_oversample_channels_get(&numIn, &numOut); + + json_t *numInJ = json_real(numIn); + json_object_set_new(rootJ, "oversampleNumIn", numInJ); + + json_t *numOutJ = json_real(numOut); + json_object_set_new(rootJ, "oversampleNumOut", numOutJ); + } + + // idleDetectInstr + { + int idleMode = vst2_idle_detect_mode_instr_get(); + + json_t *idleJ = json_integer(idleMode); + json_object_set_new(rootJ, "idleDetectInstr", idleJ); + } + + // idleDetectFx + { + int idleMode = vst2_idle_detect_mode_fx_get(); + + json_t *idleJ = json_integer(idleMode); + json_object_set_new(rootJ, "idleDetectFx", idleJ); + } + // allowCursorLock json_t *allowCursorLockJ = json_boolean(global_ui->window.gAllowCursorLock); json_object_set_new(rootJ, "allowCursorLock", allowCursorLockJ); @@ -87,6 +178,8 @@ static json_t *settingsToJson() { // checkVersion json_object_set_new(rootJ, "checkVersion", json_boolean(global_ui->app.gCheckVersion)); +#endif // RACK_HOST + return rootJ; } @@ -107,7 +200,9 @@ static void settingsFromJson(json_t *rootJ, bool bWindowSizeOnly) { { global_ui->window.windowWidth = int(width); global_ui->window.windowHeight = int(height); +#ifdef RACK_HOST vst2_window_size_set((int)width, (int)height); +#endif // RACK_HOST return; } #else @@ -146,7 +241,9 @@ static void settingsFromJson(json_t *rootJ, bool bWindowSizeOnly) { // (note) <15: use DAW timer (effEditIdle) json_t *refreshJ = json_object_get(rootJ, "refreshRate"); if (refreshJ) { +#ifdef RACK_HOST vst2_refresh_rate_set(clamp((float) json_number_value(refreshJ), 0.0f, 200.0f)); +#endif // RACK_HOST } // vsync @@ -156,7 +253,7 @@ static void settingsFromJson(json_t *rootJ, bool bWindowSizeOnly) { if (vsyncJ) { lglw_glcontext_push(global_ui->window.lglw); - lglw_swap_interval(global_ui->window.lglw, json_is_true(vsyncJ)); + lglw_swap_interval_set(global_ui->window.lglw, json_is_true(vsyncJ)); lglw_glcontext_pop(global_ui->window.lglw); } } diff --git a/src/vst2_main.cpp b/src/vst2_main.cpp index afdf89a8..fd19135e 100644 --- a/src/vst2_main.cpp +++ b/src/vst2_main.cpp @@ -18,7 +18,7 @@ /// created: 25Jun2018 /// changed: 26Jun2018, 27Jun2018, 29Jun2018, 01Jul2018, 02Jul2018, 06Jul2018, 13Jul2018 /// 26Jul2018, 04Aug2018, 05Aug2018, 06Aug2018, 07Aug2018, 09Aug2018, 11Aug2018 -/// 18Aug2018, 19Aug2018 +/// 18Aug2018, 19Aug2018, 05Sep2018 /// /// @@ -458,6 +458,8 @@ public: bool b_check_offline; // true=ask host if it's in offline rendering mode sUI idle_detect_mode; + sUI idle_detect_mode_fx; + sUI idle_detect_mode_instr; sF32 idle_input_level_threshold; sF32 idle_output_level_threshold; sF32 idle_output_sec_threshold; @@ -563,6 +565,8 @@ public: editor_rect.right = EDITWIN_X + _width; editor_rect.bottom = EDITWIN_Y + _height; + + (void)lglw_window_resize(rack_global_ui.window.lglw, _width, _height); } void setRefreshRate(float _hz) { @@ -570,6 +574,23 @@ public: redraw_ival_ms = 0u; else redraw_ival_ms = sUI(1000.0f / _hz); + + if(b_editor_open) + { + lglw_timer_stop(rack_global_ui.window.lglw); + + if(0u != redraw_ival_ms) + { + lglw_timer_start(rack_global_ui.window.lglw, redraw_ival_ms); + } + } + } + + float getRefreshRate(void) { + if(redraw_ival_ms > 0u) + return (1000.0f / redraw_ival_ms); + else + return 0.0f; } void destroyResamplerStates(void) { @@ -891,6 +912,20 @@ public: idle_output_framecount = 0u; } + void setIdleDetectModeFx(uint32_t _mode) { + idle_detect_mode_fx = _mode; +#ifdef VST2_EFFECT + setIdleDetectMode(uint32_t(_mode)); +#endif // VST2_EFFECT + } + + void setIdleDetectModeInstr(uint32_t _mode) { + idle_detect_mode_instr = _mode; +#ifndef VST2_EFFECT + setIdleDetectMode(uint32_t(_mode)); +#endif // VST2_EFFECT + } + sUI getProgramChunk(uint8_t**_addr) { setGlobals(); vst2_set_shared_plugin_tls_globals(); @@ -1719,6 +1754,12 @@ VstIntPtr VSTPluginDispatcher(VSTPlugin *vstPlugin, if(NULL != ptr) { // ... + printf("xxx vstrack_plugin: effEditGetRect: (%d; %d; %d; %d)\n", + wrapper->editor_rect.top, + wrapper->editor_rect.left, + wrapper->editor_rect.bottom, + wrapper->editor_rect.right + ); *(void**)ptr = (void*) &wrapper->editor_rect; r = 1; } @@ -1936,6 +1977,8 @@ VSTPluginWrapper::VSTPluginWrapper(audioMasterCallback vstHostCallback, b_check_offline = false; idle_detect_mode = IDLE_DETECT_NONE; + idle_detect_mode_fx = IDLE_DETECT_AUDIO; + idle_detect_mode_instr = IDLE_DETECT_MIDI; b_idle = false; idle_input_level_threshold = 0.00018f;//0.00007f; idle_output_level_threshold = 0.00018f;//0.00003f; @@ -1997,6 +2040,10 @@ void vst2_refresh_rate_set(float _hz) { rack::global->vst2.wrapper->setRefreshRate(_hz); } +float vst2_refresh_rate_get(void) { + return rack::global->vst2.wrapper->getRefreshRate(); +} + extern "C" void lglw_timer_cbk(lglw_t _lglw) { VSTPluginWrapper *wrapper = (VSTPluginWrapper*)lglw_userdata_get(_lglw); wrapper->queueRedraw(); @@ -2029,6 +2076,10 @@ void vst2_oversample_offline_check_set(int _bEnable) { rack::global->vst2.wrapper->b_check_offline = (0 != _bEnable); } +int32_t vst2_oversample_offline_check_get(void) { + return int32_t(rack::global->vst2.wrapper->b_check_offline); +} + void vst2_oversample_channels_set(int _numIn, int _numOut) { rack::global->vst2.wrapper->setOversampleChannels(_numIn, _numOut); } @@ -2039,15 +2090,19 @@ void vst2_oversample_channels_get(int *_numIn, int *_numOut) { } void vst2_idle_detect_mode_fx_set(int _mode) { -#ifdef VST2_EFFECT - rack::global->vst2.wrapper->setIdleDetectMode(uint32_t(_mode)); -#endif // VST2_EFFECT + rack::global->vst2.wrapper->setIdleDetectModeFx(uint32_t(_mode)); +} + +int vst2_idle_detect_mode_fx_get(void) { + return rack::global->vst2.wrapper->idle_detect_mode_fx; } void vst2_idle_detect_mode_instr_set(int _mode) { -#ifndef VST2_EFFECT - rack::global->vst2.wrapper->setIdleDetectMode(uint32_t(_mode)); -#endif // VST2_EFFECT + rack::global->vst2.wrapper->setIdleDetectModeInstr(uint32_t(_mode)); +} + +int vst2_idle_detect_mode_instr_get(void) { + return rack::global->vst2.wrapper->idle_detect_mode_instr; } void vst2_idle_detect_mode_set(int _mode) { diff --git a/src/widgets/QuantityWidget.cpp b/src/widgets/QuantityWidget.cpp index 9f3a00af..02e5e551 100644 --- a/src/widgets/QuantityWidget.cpp +++ b/src/widgets/QuantityWidget.cpp @@ -45,7 +45,7 @@ std::string QuantityWidget::getText() { } void QuantityWidget::onMouseLeave(EventMouseLeave &e) { - revert_val = INVALID_REVERT_VAL; + // // revert_val = INVALID_REVERT_VAL; } } // namespace rack diff --git a/src/window.cpp b/src/window.cpp index 4a2135a5..b652bff4 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -374,7 +374,7 @@ void windowInit() { global_ui->window.lastWindowTitle = ""; lglw_glcontext_push(global_ui->window.lglw); - lglw_swap_interval(global_ui->window.lglw, 1); // can be overridden via settings.json:"vsync" property + lglw_swap_interval_set(global_ui->window.lglw, 1); // can be overridden via settings.json:"vsync" property lglw_mouse_callback_set (global_ui->window.lglw, &lglw_mouse_cbk); lglw_focus_callback_set (global_ui->window.lglw, &lglw_focus_cbk); diff --git a/vst2_bin/res/icons/LICENSE_settings_icon.txt b/vst2_bin/res/icons/LICENSE_settings_icon.txt new file mode 100644 index 00000000..87e156fe --- /dev/null +++ b/vst2_bin/res/icons/LICENSE_settings_icon.txt @@ -0,0 +1 @@ +
Icons made by Egor Rumyantsev from www.flaticon.com is licensed by CC 3.0 BY
diff --git a/vst2_bin/res/icons/settings_icon_cc.svg b/vst2_bin/res/icons/settings_icon_cc.svg new file mode 100644 index 00000000..3637457e --- /dev/null +++ b/vst2_bin/res/icons/settings_icon_cc.svg @@ -0,0 +1,78 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file