1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2020 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 #include "DistrhoUIInternal.hpp"
18 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
19 # include "src/WidgetPrivateData.hpp"
20 #endif
21 
22 START_NAMESPACE_DISTRHO
23 
24 /* ------------------------------------------------------------------------------------------------------------
25  * Static data, see DistrhoUIInternal.hpp */
26 
27 double      d_lastUiSampleRate = 0.0;
28 void*       d_lastUiDspPtr     = nullptr;
29 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
30 const char* g_nextBundlePath   = nullptr;
31 double      g_nextScaleFactor  = 1.0;
32 uintptr_t   g_nextWindowId     = 0;
33 #else
34 Window*     d_lastUiWindow     = nullptr;
35 #endif
36 
37 /* ------------------------------------------------------------------------------------------------------------
38  * UI */
39 
40 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
UI(uint width,uint height)41 UI::UI(uint width, uint height)
42     : UIWidget(width, height),
43       pData(new PrivateData()) {}
44 #else
UI(uint width,uint height)45 UI::UI(uint width, uint height)
46     : UIWidget(*d_lastUiWindow),
47       pData(new PrivateData())
48 {
49     ((UIWidget*)this)->pData->needsFullViewport = false;
50 
51     if (width > 0 && height > 0)
52         setSize(width, height);
53 }
54 #endif
55 
~UI()56 UI::~UI()
57 {
58     delete pData;
59 }
60 
61 #if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
setGeometryConstraints(uint minWidth,uint minHeight,bool keepAspectRatio,bool automaticallyScale)62 void UI::setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale)
63 {
64     DISTRHO_SAFE_ASSERT_RETURN(minWidth > 0,);
65     DISTRHO_SAFE_ASSERT_RETURN(minHeight > 0,);
66 
67     pData->automaticallyScale = automaticallyScale;
68     pData->minWidth = minWidth;
69     pData->minHeight = minHeight;
70 
71     Window& window(getParentWindow());
72 
73     const double uiScaleFactor = window.getScaling();
74     window.setGeometryConstraints(minWidth * uiScaleFactor, minHeight * uiScaleFactor, keepAspectRatio);
75 
76     if (d_isNotZero(uiScaleFactor - 1.0))
77         setSize(getWidth() * uiScaleFactor, getHeight() * uiScaleFactor);
78 }
79 #endif
80 
81 /* ------------------------------------------------------------------------------------------------------------
82  * Host state */
83 
getBackgroundColor() const84 uint UI::getBackgroundColor() const noexcept
85 {
86     return pData->bgColor;
87 }
88 
getForegroundColor() const89 uint UI::getForegroundColor() const noexcept
90 {
91     return pData->fgColor;
92 }
93 
getSampleRate() const94 double UI::getSampleRate() const noexcept
95 {
96     return pData->sampleRate;
97 }
98 
editParameter(uint32_t index,bool started)99 void UI::editParameter(uint32_t index, bool started)
100 {
101     pData->editParamCallback(index + pData->parameterOffset, started);
102 }
103 
setParameterValue(uint32_t index,float value)104 void UI::setParameterValue(uint32_t index, float value)
105 {
106     pData->setParamCallback(index + pData->parameterOffset, value);
107 }
108 
109 #if DISTRHO_PLUGIN_WANT_STATE
setState(const char * key,const char * value)110 void UI::setState(const char* key, const char* value)
111 {
112     pData->setStateCallback(key, value);
113 }
114 #endif
115 
116 #if DISTRHO_PLUGIN_WANT_STATEFILES
requestStateFile(const char * key)117 bool UI::requestStateFile(const char* key)
118 {
119     return pData->fileRequestCallback(key);
120 }
121 #endif
122 
123 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
sendNote(uint8_t channel,uint8_t note,uint8_t velocity)124 void UI::sendNote(uint8_t channel, uint8_t note, uint8_t velocity)
125 {
126     pData->sendNoteCallback(channel, note, velocity);
127 }
128 #endif
129 
130 #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
131 /* ------------------------------------------------------------------------------------------------------------
132  * Direct DSP access */
133 
getPluginInstancePointer() const134 void* UI::getPluginInstancePointer() const noexcept
135 {
136     return pData->dspPtr;
137 }
138 #endif
139 
140 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
141 /* ------------------------------------------------------------------------------------------------------------
142  * External UI helpers */
143 
getNextBundlePath()144 const char* UI::getNextBundlePath() noexcept
145 {
146     return g_nextBundlePath;
147 }
148 
getNextScaleFactor()149 double UI::getNextScaleFactor() noexcept
150 {
151     return g_nextScaleFactor;
152 }
153 
154 # if DISTRHO_PLUGIN_HAS_EMBED_UI
getNextWindowId()155 uintptr_t UI::getNextWindowId() noexcept
156 {
157     return g_nextWindowId;
158 }
159 # endif
160 #endif
161 
162 /* ------------------------------------------------------------------------------------------------------------
163  * DSP/Plugin Callbacks (optional) */
164 
sampleRateChanged(double)165 void UI::sampleRateChanged(double) {}
166 
167 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
168 /* ------------------------------------------------------------------------------------------------------------
169  * UI Callbacks (optional) */
170 
171 # ifndef DGL_FILE_BROWSER_DISABLED
uiFileBrowserSelected(const char *)172 void UI::uiFileBrowserSelected(const char*)
173 {
174 }
175 # endif
176 
uiReshape(uint width,uint height)177 void UI::uiReshape(uint width, uint height)
178 {
179 #ifdef DGL_OPENGL
180     glEnable(GL_BLEND);
181     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
182     glMatrixMode(GL_PROJECTION);
183     glLoadIdentity();
184     glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0);
185     glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
186     glMatrixMode(GL_MODELVIEW);
187     glLoadIdentity();
188 #else
189     // unused
190     (void)width;
191     (void)height;
192 #endif
193 }
194 
195 /* ------------------------------------------------------------------------------------------------------------
196  * UI Resize Handling, internal */
197 
onResize(const ResizeEvent & ev)198 void UI::onResize(const ResizeEvent& ev)
199 {
200     if (pData->resizeInProgress)
201         return;
202 
203     pData->setSizeCallback(ev.size.getWidth(), ev.size.getHeight());
204 }
205 #endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
206 
207 // -----------------------------------------------------------------------------------------------------------
208 
209 END_NAMESPACE_DISTRHO
210