| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -77,7 +77,7 @@ public: | |||||
| explicit Window(Application& app); | explicit Window(Application& app); | ||||
| explicit Window(Application& app, Window& parent); | explicit Window(Application& app, Window& parent); | ||||
| explicit Window(Application& app, intptr_t parentId); | |||||
| explicit Window(Application& app, intptr_t parentId, bool resizable); | |||||
| virtual ~Window(); | virtual ~Window(); | ||||
| void show(); | void show(); | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -147,13 +147,13 @@ struct Window::PrivateData { | |||||
| #endif | #endif | ||||
| } | } | ||||
| PrivateData(Application& app, Window* const self, const intptr_t parentId) | |||||
| PrivateData(Application& app, Window* const self, const intptr_t parentId, const bool resizable) | |||||
| : fApp(app), | : fApp(app), | ||||
| fSelf(self), | fSelf(self), | ||||
| fView(puglInit()), | fView(puglInit()), | ||||
| fFirstInit(true), | fFirstInit(true), | ||||
| fVisible(parentId != 0), | fVisible(parentId != 0), | ||||
| fResizable(parentId == 0), | |||||
| fResizable(resizable), | |||||
| fUsingEmbed(parentId != 0), | fUsingEmbed(parentId != 0), | ||||
| fWidth(1), | fWidth(1), | ||||
| fHeight(1), | fHeight(1), | ||||
| @@ -1155,8 +1155,8 @@ Window::Window(Application& app) | |||||
| Window::Window(Application& app, Window& parent) | Window::Window(Application& app, Window& parent) | ||||
| : pData(new PrivateData(app, this, parent)) {} | : pData(new PrivateData(app, this, parent)) {} | ||||
| Window::Window(Application& app, intptr_t parentId) | |||||
| : pData(new PrivateData(app, this, parentId)) {} | |||||
| Window::Window(Application& app, intptr_t parentId, bool resizable) | |||||
| : pData(new PrivateData(app, this, parentId, resizable)) {} | |||||
| Window::~Window() | Window::~Window() | ||||
| { | { | ||||
| @@ -1213,6 +1213,7 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||||
| String startDir(options.startDir); | String startDir(options.startDir); | ||||
| # ifdef DISTRHO_OS_LINUX | |||||
| if (startDir.isEmpty()) | if (startDir.isEmpty()) | ||||
| { | { | ||||
| if (char* const dir_name = get_current_dir_name()) | if (char* const dir_name = get_current_dir_name()) | ||||
| @@ -1221,6 +1222,7 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||||
| std::free(dir_name); | std::free(dir_name); | ||||
| } | } | ||||
| } | } | ||||
| # endif | |||||
| DISTRHO_SAFE_ASSERT_RETURN(startDir.isNotEmpty(), false); | DISTRHO_SAFE_ASSERT_RETURN(startDir.isNotEmpty(), false); | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -555,6 +555,14 @@ START_NAMESPACE_DISTRHO | |||||
| */ | */ | ||||
| #define DISTRHO_UI_USE_NANOVG 1 | #define DISTRHO_UI_USE_NANOVG 1 | ||||
| /** | |||||
| Wherever the %UI is resizable to any size by the user.@n | |||||
| By default this is false, and resizing is only allowed under the plugin UI control,@n | |||||
| Enabling this options makes it possible for the user to resize the plugin UI at anytime. | |||||
| @see UI::setGeometryConstraints(uint, uint, bool, bool) | |||||
| */ | |||||
| #define DISTRHO_UI_USER_RESIZABLE 1 | |||||
| /** | /** | ||||
| The %UI URI when exporting in LV2 format.@n | The %UI URI when exporting in LV2 format.@n | ||||
| By default this is set to @ref DISTRHO_PLUGIN_URI with "#UI" as suffix. | By default this is set to @ref DISTRHO_PLUGIN_URI with "#UI" as suffix. | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -55,19 +55,13 @@ public: | |||||
| UI class constructor. | UI class constructor. | ||||
| The UI should be initialized to a default state that matches the plugin side. | The UI should be initialized to a default state that matches the plugin side. | ||||
| */ | */ | ||||
| UI(uint width = 0, uint height = 0, bool userResizable = false); | |||||
| UI(uint width = 0, uint height = 0); | |||||
| /** | /** | ||||
| Destructor. | Destructor. | ||||
| */ | */ | ||||
| virtual ~UI(); | virtual ~UI(); | ||||
| /** | |||||
| Wherever this UI is resizable by the user. | |||||
| This simply returns the value passed in the constructor. | |||||
| */ | |||||
| bool isUserResizable() const noexcept; | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| /** | /** | ||||
| Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically. | Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically. | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -85,6 +85,10 @@ | |||||
| # define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | # define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | ||||
| #endif | #endif | ||||
| #ifndef DISTRHO_UI_USER_RESIZABLE | |||||
| # define DISTRHO_UI_USER_RESIZABLE 0 | |||||
| #endif | |||||
| #ifndef DISTRHO_UI_USE_NANOVG | #ifndef DISTRHO_UI_USE_NANOVG | ||||
| # define DISTRHO_UI_USE_NANOVG 0 | # define DISTRHO_UI_USE_NANOVG 0 | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -139,12 +139,17 @@ void lv2_generate_ttl(const char* const basename) | |||||
| # endif | # endif | ||||
| manifestString += "\n"; | manifestString += "\n"; | ||||
| # if DISTRHO_PLUGIN_HAS_EMBED_UI | # if DISTRHO_PLUGIN_HAS_EMBED_UI | ||||
| // TODO: pluginUI.isUserResizable() | |||||
| # if DISTRHO_UI_USER_RESIZABLE | |||||
| manifestString += " lv2:optionalFeature ui:resize ,\n"; | |||||
| manifestString += " ui:touch ;\n"; | |||||
| manifestString += "\n"; | |||||
| # else // DISTRHO_UI_USER_RESIZABLE | |||||
| manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; | manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; | ||||
| manifestString += " ui:resize ,\n"; | manifestString += " ui:resize ,\n"; | ||||
| manifestString += " ui:touch ;\n"; | manifestString += " ui:touch ;\n"; | ||||
| manifestString += "\n"; | manifestString += "\n"; | ||||
| # endif | |||||
| # endif // DISTRHO_UI_USER_RESIZABLE | |||||
| # endif // DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n"; | manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n"; | ||||
| manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; | manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; | ||||
| manifestString += " <" LV2_OPTIONS__options "> ,\n"; | manifestString += " <" LV2_OPTIONS__options "> ,\n"; | ||||
| @@ -630,12 +635,17 @@ void lv2_generate_ttl(const char* const basename) | |||||
| # endif | # endif | ||||
| uiString += "\n"; | uiString += "\n"; | ||||
| # if DISTRHO_PLUGIN_HAS_EMBED_UI | # if DISTRHO_PLUGIN_HAS_EMBED_UI | ||||
| // TODO: pluginUI.isUserResizable() | |||||
| # if DISTRHO_UI_USER_RESIZABLE | |||||
| uiString += " lv2:optionalFeature ui:resize ,\n"; | |||||
| uiString += " ui:touch ;\n"; | |||||
| uiString += "\n"; | |||||
| # else // DISTRHO_UI_USER_RESIZABLE | |||||
| uiString += " lv2:optionalFeature ui:noUserResize ,\n"; | uiString += " lv2:optionalFeature ui:noUserResize ,\n"; | ||||
| uiString += " ui:resize ,\n"; | uiString += " ui:resize ,\n"; | ||||
| uiString += " ui:touch ;\n"; | uiString += " ui:touch ;\n"; | ||||
| uiString += "\n"; | uiString += "\n"; | ||||
| # endif | |||||
| # endif // DISTRHO_UI_USER_RESIZABLE | |||||
| # endif // DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | ||||
| uiString += " <" LV2_URID__map "> ;\n"; | uiString += " <" LV2_URID__map "> ;\n"; | ||||
| @@ -972,15 +972,23 @@ public: | |||||
| if (vstTimeInfo->flags & (kVstPpqPosValid|kVstTimeSigValid)) | if (vstTimeInfo->flags & (kVstPpqPosValid|kVstTimeSigValid)) | ||||
| { | { | ||||
| const int ppqPerBar = vstTimeInfo->timeSigNumerator * 4 / vstTimeInfo->timeSigDenominator; | |||||
| const double barBeats = (std::fmod(vstTimeInfo->ppqPos, ppqPerBar) / ppqPerBar) * vstTimeInfo->timeSigNumerator; | |||||
| const double ppqPos = std::abs(vstTimeInfo->ppqPos); | |||||
| const double ppqPerBar = static_cast<double>(vstTimeInfo->timeSigNumerator * 4) / vstTimeInfo->timeSigDenominator; | |||||
| const double barBeats = (std::fmod(ppqPos, ppqPerBar) / ppqPerBar) * vstTimeInfo->timeSigNumerator; | |||||
| const double rest = std::fmod(barBeats, 1.0); | const double rest = std::fmod(barBeats, 1.0); | ||||
| fTimePosition.bbt.bar = int(vstTimeInfo->ppqPos)/ppqPerBar + 1; | |||||
| fTimePosition.bbt.beat = barBeats-rest+1; | |||||
| fTimePosition.bbt.tick = rest*fTimePosition.bbt.ticksPerBeat+0.5; | |||||
| fTimePosition.bbt.bar = static_cast<int32_t>(ppqPos / ppqPerBar + 0.5) + 1; | |||||
| fTimePosition.bbt.beat = static_cast<int32_t>(barBeats + 0.5) + 1; | |||||
| fTimePosition.bbt.tick = static_cast<int32_t>(rest * fTimePosition.bbt.ticksPerBeat + 0.5); | |||||
| fTimePosition.bbt.beatsPerBar = vstTimeInfo->timeSigNumerator; | fTimePosition.bbt.beatsPerBar = vstTimeInfo->timeSigNumerator; | ||||
| fTimePosition.bbt.beatType = vstTimeInfo->timeSigDenominator; | fTimePosition.bbt.beatType = vstTimeInfo->timeSigDenominator; | ||||
| if (vstTimeInfo->ppqPos < 0.0) | |||||
| { | |||||
| --fTimePosition.bbt.bar; | |||||
| fTimePosition.bbt.beat = vstTimeInfo->timeSigNumerator - fTimePosition.bbt.beat + 1; | |||||
| fTimePosition.bbt.tick = int(fTimePosition.bbt.ticksPerBeat) - fTimePosition.bbt.tick - 1; | |||||
| } | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -37,13 +37,13 @@ Window* d_lastUiWindow = nullptr; | |||||
| * UI */ | * UI */ | ||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| UI::UI(uint width, uint height, bool userResizable) | |||||
| UI::UI(uint width, uint height) | |||||
| : UIWidget(width, height), | : UIWidget(width, height), | ||||
| pData(new PrivateData(userResizable)) {} | |||||
| pData(new PrivateData()) {} | |||||
| #else | #else | ||||
| UI::UI(uint width, uint height, bool userResizable) | |||||
| UI::UI(uint width, uint height) | |||||
| : UIWidget(*d_lastUiWindow), | : UIWidget(*d_lastUiWindow), | ||||
| pData(new PrivateData(userResizable)) | |||||
| pData(new PrivateData()) | |||||
| { | { | ||||
| ((UIWidget*)this)->pData->needsFullViewport = false; | ((UIWidget*)this)->pData->needsFullViewport = false; | ||||
| @@ -57,11 +57,6 @@ UI::~UI() | |||||
| delete pData; | delete pData; | ||||
| } | } | ||||
| bool UI::isUserResizable() const noexcept | |||||
| { | |||||
| return pData->userResizable; | |||||
| } | |||||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale) | void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale) | ||||
| { | { | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -64,7 +64,6 @@ struct UI::PrivateData { | |||||
| #endif | #endif | ||||
| // UI | // UI | ||||
| const bool userResizable; | |||||
| bool automaticallyScale; | bool automaticallyScale; | ||||
| bool resizeInProgress; | bool resizeInProgress; | ||||
| uint minWidth; | uint minWidth; | ||||
| @@ -78,13 +77,12 @@ struct UI::PrivateData { | |||||
| sendNoteFunc sendNoteCallbackFunc; | sendNoteFunc sendNoteCallbackFunc; | ||||
| setSizeFunc setSizeCallbackFunc; | setSizeFunc setSizeCallbackFunc; | ||||
| PrivateData(const bool resizable) noexcept | |||||
| PrivateData() noexcept | |||||
| : sampleRate(d_lastUiSampleRate), | : sampleRate(d_lastUiSampleRate), | ||||
| parameterOffset(0), | parameterOffset(0), | ||||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | ||||
| dspPtr(d_lastUiDspPtr), | dspPtr(d_lastUiDspPtr), | ||||
| #endif | #endif | ||||
| userResizable(resizable), | |||||
| automaticallyScale(false), | automaticallyScale(false), | ||||
| resizeInProgress(false), | resizeInProgress(false), | ||||
| minWidth(0), | minWidth(0), | ||||
| @@ -178,14 +176,13 @@ class UIExporterWindow : public Window | |||||
| { | { | ||||
| public: | public: | ||||
| UIExporterWindow(Application& app, const intptr_t winId, void* const dspPtr) | UIExporterWindow(Application& app, const intptr_t winId, void* const dspPtr) | ||||
| : Window(app, winId), | |||||
| : Window(app, winId, DISTRHO_UI_USER_RESIZABLE), | |||||
| fUI(createUiWrapper(dspPtr, this)), | fUI(createUiWrapper(dspPtr, this)), | ||||
| fIsReady(false) | fIsReady(false) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI->pData != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI->pData != nullptr,); | ||||
| setResizable(fUI->pData->userResizable); | |||||
| setSize(fUI->getWidth(), fUI->getHeight()); | setSize(fUI->getWidth(), fUI->getHeight()); | ||||
| } | } | ||||