1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any purpose with 6 * or without fee is hereby granted, provided that the above copyright notice and this 7 * permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN 11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef DISTRHO_UI_INTERNAL_HPP_INCLUDED 18 #define DISTRHO_UI_INTERNAL_HPP_INCLUDED 19 20 #include "DistrhoUIPrivateData.hpp" 21 22 START_NAMESPACE_DISTRHO 23 24 // ----------------------------------------------------------------------- 25 // Static data, see DistrhoUI.cpp 26 27 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI 28 extern uintptr_t g_nextWindowId; 29 extern double g_nextScaleFactor; 30 extern const char* g_nextBundlePath; 31 #endif 32 33 // ----------------------------------------------------------------------- 34 // UI exporter class 35 36 class UIExporter 37 { 38 // ------------------------------------------------------------------- 39 // UI Widget and its private data 40 41 UI* ui; 42 UI::PrivateData* uiData; 43 44 // ------------------------------------------------------------------- 45 46 public: UIExporter(void * const callbacksPtr,const uintptr_t winId,const double sampleRate,const editParamFunc editParamCall,const setParamFunc setParamCall,const setStateFunc setStateCall,const sendNoteFunc sendNoteCall,const setSizeFunc setSizeCall,const fileRequestFunc fileRequestCall,const char * const bundlePath=nullptr,void * const dspPtr=nullptr,const double scaleFactor=0.0,const uint32_t bgColor=0,const uint32_t fgColor=0xffffffff)47 UIExporter(void* const callbacksPtr, 48 const uintptr_t winId, 49 const double sampleRate, 50 const editParamFunc editParamCall, 51 const setParamFunc setParamCall, 52 const setStateFunc setStateCall, 53 const sendNoteFunc sendNoteCall, 54 const setSizeFunc setSizeCall, 55 const fileRequestFunc fileRequestCall, 56 const char* const bundlePath = nullptr, 57 void* const dspPtr = nullptr, 58 const double scaleFactor = 0.0, 59 const uint32_t bgColor = 0, 60 const uint32_t fgColor = 0xffffffff) 61 : ui(nullptr), 62 uiData(new UI::PrivateData()) 63 { 64 uiData->sampleRate = sampleRate; 65 uiData->dspPtr = dspPtr; 66 67 uiData->bgColor = bgColor; 68 uiData->fgColor = fgColor; 69 uiData->scaleFactor = scaleFactor; 70 uiData->winId = winId; 71 72 uiData->callbacksPtr = callbacksPtr; 73 uiData->editParamCallbackFunc = editParamCall; 74 uiData->setParamCallbackFunc = setParamCall; 75 uiData->setStateCallbackFunc = setStateCall; 76 uiData->sendNoteCallbackFunc = sendNoteCall; 77 uiData->setSizeCallbackFunc = setSizeCall; 78 uiData->fileRequestCallbackFunc = fileRequestCall; 79 80 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI 81 g_nextWindowId = winId; 82 g_nextScaleFactor = scaleFactor; 83 g_nextBundlePath = bundlePath; 84 #endif 85 UI::PrivateData::s_nextPrivateData = uiData; 86 87 UI* const uiPtr = createUI(); 88 89 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI 90 g_nextWindowId = 0; 91 g_nextScaleFactor = 0.0; 92 g_nextBundlePath = nullptr; 93 #else 94 // Leave context called in the PluginWindow constructor, see DistrhoUIPrivateData.hpp 95 uiData->window->leaveContext(); 96 #endif 97 UI::PrivateData::s_nextPrivateData = nullptr; 98 99 DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,); 100 ui = uiPtr; 101 102 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI 103 // unused 104 (void)bundlePath; 105 #endif 106 } 107 ~UIExporter()108 ~UIExporter() 109 { 110 quit(); 111 delete ui; 112 delete uiData; 113 } 114 115 // ------------------------------------------------------------------- 116 getWidth() const117 uint getWidth() const noexcept 118 { 119 return uiData->window->getWidth(); 120 } 121 getHeight() const122 uint getHeight() const noexcept 123 { 124 return uiData->window->getHeight(); 125 } 126 getScaleFactor() const127 double getScaleFactor() const noexcept 128 { 129 return uiData->window->getScaleFactor(); 130 } 131 isVisible() const132 bool isVisible() const noexcept 133 { 134 return uiData->window->isVisible(); 135 } 136 getNativeWindowHandle() const137 uintptr_t getNativeWindowHandle() const noexcept 138 { 139 return uiData->window->getNativeWindowHandle(); 140 } 141 getBackgroundColor() const142 uint getBackgroundColor() const noexcept 143 { 144 DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0); 145 146 return uiData->bgColor; 147 } 148 getForegroundColor() const149 uint getForegroundColor() const noexcept 150 { 151 DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0xffffffff); 152 153 return uiData->fgColor; 154 } 155 156 // ------------------------------------------------------------------- 157 getParameterOffset() const158 uint32_t getParameterOffset() const noexcept 159 { 160 DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0); 161 162 return uiData->parameterOffset; 163 } 164 165 // ------------------------------------------------------------------- 166 parameterChanged(const uint32_t index,const float value)167 void parameterChanged(const uint32_t index, const float value) 168 { 169 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); 170 171 ui->parameterChanged(index, value); 172 } 173 174 #if DISTRHO_PLUGIN_WANT_PROGRAMS programLoaded(const uint32_t index)175 void programLoaded(const uint32_t index) 176 { 177 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); 178 179 ui->programLoaded(index); 180 } 181 #endif 182 183 #if DISTRHO_PLUGIN_WANT_STATE stateChanged(const char * const key,const char * const value)184 void stateChanged(const char* const key, const char* const value) 185 { 186 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); 187 DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); 188 DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,); 189 190 ui->stateChanged(key, value); 191 } 192 #endif 193 194 // ------------------------------------------------------------------- 195 196 #if DISTRHO_UI_IS_STANDALONE exec(DGL_NAMESPACE::IdleCallback * const cb)197 void exec(DGL_NAMESPACE::IdleCallback* const cb) 198 { 199 DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); 200 201 uiData->window->show(); 202 uiData->window->focus(); 203 uiData->app.addIdleCallback(cb); 204 uiData->app.exec(); 205 } 206 exec_idle()207 void exec_idle() 208 { 209 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, ); 210 211 ui->uiIdle(); 212 } 213 #else plugin_idle()214 bool plugin_idle() 215 { 216 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false); 217 218 uiData->app.idle(); 219 ui->uiIdle(); 220 return ! uiData->app.isQuitting(); 221 } 222 #endif 223 focus()224 void focus() 225 { 226 uiData->window->focus(); 227 } 228 quit()229 void quit() 230 { 231 uiData->window->close(); 232 uiData->app.quit(); 233 } 234 235 // ------------------------------------------------------------------- 236 setWindowTitle(const char * const uiTitle)237 void setWindowTitle(const char* const uiTitle) 238 { 239 uiData->window->setTitle(uiTitle); 240 } 241 setWindowTransientWinId(const uintptr_t winId)242 void setWindowTransientWinId(const uintptr_t winId) 243 { 244 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI 245 ui->setTransientWindowId(winId); 246 #elif 0 /* TODO */ 247 glWindow.setTransientWinId(winId); 248 #else 249 (void)winId; 250 #endif 251 } 252 setWindowVisible(const bool yesNo)253 bool setWindowVisible(const bool yesNo) 254 { 255 uiData->window->setVisible(yesNo); 256 257 return ! uiData->app.isQuitting(); 258 } 259 260 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI handlePluginKeyboard(const bool press,const uint key,const uint16_t mods)261 bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) 262 { 263 // TODO also trigger Character input event 264 DGL_NAMESPACE::Widget::KeyboardEvent ev; 265 ev.press = press; 266 ev.key = key; 267 ev.mod = mods; 268 return ui->onKeyboard(ev); 269 } 270 handlePluginSpecial(const bool press,const DGL_NAMESPACE::Key key,const uint16_t mods)271 bool handlePluginSpecial(const bool press, const DGL_NAMESPACE::Key key, const uint16_t mods) 272 { 273 DGL_NAMESPACE::Widget::SpecialEvent ev; 274 ev.press = press; 275 ev.key = key; 276 ev.mod = mods; 277 return ui->onSpecial(ev); 278 } 279 #endif 280 281 // ------------------------------------------------------------------- 282 notifyScaleFactorChanged(const double scaleFactor)283 void notifyScaleFactorChanged(const double scaleFactor) 284 { 285 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); 286 287 ui->uiScaleFactorChanged(scaleFactor); 288 } 289 setSampleRate(const double sampleRate,const bool doCallback=false)290 void setSampleRate(const double sampleRate, const bool doCallback = false) 291 { 292 DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); 293 DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,); 294 DISTRHO_SAFE_ASSERT(sampleRate > 0.0); 295 296 if (d_isEqual(uiData->sampleRate, sampleRate)) 297 return; 298 299 uiData->sampleRate = sampleRate; 300 301 if (doCallback) 302 ui->sampleRateChanged(sampleRate); 303 } 304 305 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter) 306 }; 307 308 // ----------------------------------------------------------------------- 309 310 END_NAMESPACE_DISTRHO 311 312 #endif // DISTRHO_UI_INTERNAL_HPP_INCLUDED 313