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 @@
+
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 @@
+
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