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 #ifndef DISTRHO_UI_HPP_INCLUDED
18 #define DISTRHO_UI_HPP_INCLUDED
19 
20 #include "extra/LeakDetector.hpp"
21 #include "src/DistrhoPluginChecks.h"
22 
23 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
24 # include "../dgl/Base.hpp"
25 # include "extra/ExternalWindow.hpp"
26 typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget;
27 #elif DISTRHO_UI_USE_NANOVG
28 # include "../dgl/NanoVG.hpp"
29 typedef DGL_NAMESPACE::NanoWidget UIWidget;
30 #else
31 # include "../dgl/Widget.hpp"
32 typedef DGL_NAMESPACE::Widget UIWidget;
33 #endif
34 
35 #ifdef DGL_CAIRO
36 # include "Cairo.hpp"
37 #endif
38 #ifdef DGL_OPENGL
39 # include "OpenGL.hpp"
40 #endif
41 
42 START_NAMESPACE_DISTRHO
43 
44 /* ------------------------------------------------------------------------------------------------------------
45  * DPF UI */
46 
47 /**
48    @addtogroup MainClasses
49    @{
50  */
51 
52 /**
53    DPF UI class from where UI instances are created.
54 
55    @note You must call setSize during construction,
56    @TODO Detailed information about this class.
57  */
58 class UI : public UIWidget
59 {
60 public:
61    /**
62       UI class constructor.
63       The UI should be initialized to a default state that matches the plugin side.
64     */
65     UI(uint width = 0, uint height = 0);
66 
67    /**
68       Destructor.
69     */
70     virtual ~UI();
71 
72 #if DISTRHO_UI_USER_RESIZABLE && !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
73    /**
74       Set geometry constraints for the UI when resized by the user, and optionally scale UI automatically.
75       @see Window::setGeometryConstraints(uint,uint,bool)
76       @see Window::setScaling(double)
77     */
78     void setGeometryConstraints(uint minWidth, uint minHeight, bool keepAspectRatio, bool automaticallyScale = false);
79 #endif
80 
81    /* --------------------------------------------------------------------------------------------------------
82     * Host state */
83 
84    /**
85       Get the color used for UI background (i.e. window color) in RGBA format.
86       Returns 0 by default, in case of error or lack of host support.
87     */
88     uint getBackgroundColor() const noexcept;
89 
90    /**
91       Get the color used for UI foreground (i.e. text color) in RGBA format.
92       Returns 0xffffffff by default, in case of error or lack of host support.
93     */
94     uint getForegroundColor() const noexcept;
95 
96    /**
97       Get the current sample rate used in plugin processing.
98       @see sampleRateChanged(double)
99     */
100     double getSampleRate() const noexcept;
101 
102    /**
103       editParameter.
104 
105       Touch/pressed-down event.
106       Lets the host know the user is tweaking a parameter.
107       Required in some hosts to record automation.
108     */
109     void editParameter(uint32_t index, bool started);
110 
111    /**
112       setParameterValue.
113 
114       Change a parameter value in the Plugin.
115     */
116     void setParameterValue(uint32_t index, float value);
117 
118 #if DISTRHO_PLUGIN_WANT_STATE
119    /**
120       setState.
121       @TODO Document this.
122     */
123     void setState(const char* key, const char* value);
124 #endif
125 
126 #if DISTRHO_PLUGIN_WANT_STATEFILES
127    /**
128       Request a new file from the host, matching the properties of a state key.@n
129       This will use the native host file browser if available, otherwise a DPF built-in file browser is used.@n
130       Response will be sent asynchronously to stateChanged, with the matching key and the new file as the value.@n
131       It is not possible to know if the action was cancelled by the user.
132 
133       @return Success if a file-browser was opened, otherwise false.
134       @note You cannot request more than one file at a time.
135     */
136     bool requestStateFile(const char* key);
137 #endif
138 
139 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
140    /**
141       sendNote.
142       @TODO Document this.
143       @note Work in progress. Implemented for DSSI and LV2 formats.
144     */
145     void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
146 #endif
147 
148 #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
149    /* --------------------------------------------------------------------------------------------------------
150     * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */
151 
152    /**
153       getPluginInstancePointer.
154       @TODO Document this.
155     */
156     void* getPluginInstancePointer() const noexcept;
157 #endif
158 
159 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
160    /* --------------------------------------------------------------------------------------------------------
161     * External UI helpers */
162 
163    /**
164       Get the bundle path that will be used for the next UI.
165       @note: This function is only valid during createUI(),
166              it will return null when called from anywhere else.
167     */
168     static const char* getNextBundlePath() noexcept;
169 
170    /**
171       Get the scale factor that will be used for the next UI.
172       @note: This function is only valid during createUI(),
173              it will return 1.0 when called from anywhere else.
174     */
175     static double getNextScaleFactor() noexcept;
176 
177 # if DISTRHO_PLUGIN_HAS_EMBED_UI
178    /**
179       Get the Window Id that will be used for the next created window.
180       @note: This function is only valid during createUI(),
181              it will return 0 when called from anywhere else.
182     */
183     static uintptr_t getNextWindowId() noexcept;
184 # endif
185 #endif
186 
187 protected:
188    /* --------------------------------------------------------------------------------------------------------
189     * DSP/Plugin Callbacks */
190 
191    /**
192       A parameter has changed on the plugin side.@n
193       This is called by the host to inform the UI about parameter changes.
194     */
195     virtual void parameterChanged(uint32_t index, float value) = 0;
196 
197 #if DISTRHO_PLUGIN_WANT_PROGRAMS
198    /**
199       A program has been loaded on the plugin side.@n
200       This is called by the host to inform the UI about program changes.
201     */
202     virtual void programLoaded(uint32_t index) = 0;
203 #endif
204 
205 #if DISTRHO_PLUGIN_WANT_STATE
206    /**
207       A state has changed on the plugin side.@n
208       This is called by the host to inform the UI about state changes.
209     */
210     virtual void stateChanged(const char* key, const char* value) = 0;
211 #endif
212 
213    /* --------------------------------------------------------------------------------------------------------
214     * DSP/Plugin Callbacks (optional) */
215 
216    /**
217       Optional callback to inform the UI about a sample rate change on the plugin side.
218       @see getSampleRate()
219     */
220     virtual void sampleRateChanged(double newSampleRate);
221 
222 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
223    /* --------------------------------------------------------------------------------------------------------
224     * UI Callbacks (optional) */
225 
226    /**
227       uiIdle.
228       @TODO Document this.
229     */
uiIdle()230     virtual void uiIdle() {}
231 
232 # ifndef DGL_FILE_BROWSER_DISABLED
233    /**
234       File browser selected function.
235       @see Window::fileBrowserSelected(const char*)
236     */
237     virtual void uiFileBrowserSelected(const char* filename);
238 # endif
239 
240    /**
241       OpenGL window reshape function, called when parent window is resized.
242       You can reimplement this function for a custom OpenGL state.
243       @see Window::onReshape(uint,uint)
244     */
245     virtual void uiReshape(uint width, uint height);
246 
247    /* --------------------------------------------------------------------------------------------------------
248     * UI Resize Handling, internal */
249 
250    /**
251       OpenGL widget resize function, called when the widget is resized.
252       This is overriden here so the host knows when the UI is resized by you.
253       @see Widget::onResize(const ResizeEvent&)
254     */
255     void onResize(const ResizeEvent& ev) override;
256 #endif
257 
258     // -------------------------------------------------------------------------------------------------------
259 
260 private:
261     struct PrivateData;
262     PrivateData* const pData;
263     friend class UIExporter;
264     friend class UIExporterWindow;
265 
266 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
267     // these should not be used
setAbsoluteX(int) const268     void setAbsoluteX(int) const noexcept {}
setAbsoluteY(int) const269     void setAbsoluteY(int) const noexcept {}
setAbsolutePos(int,int) const270     void setAbsolutePos(int, int) const noexcept {}
setAbsolutePos(const DGL_NAMESPACE::Point<int> &) const271     void setAbsolutePos(const DGL_NAMESPACE::Point<int>&) const noexcept {}
272 #endif
273 
274     DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
275 };
276 
277 /** @} */
278 
279 /* ------------------------------------------------------------------------------------------------------------
280  * Create UI, entry point */
281 
282 /**
283    @addtogroup EntryPoints
284    @{
285  */
286 
287 /**
288    createUI.
289    @TODO Document this.
290  */
291 extern UI* createUI();
292 
293 /** @} */
294 
295 // -----------------------------------------------------------------------------------------------------------
296 
297 END_NAMESPACE_DISTRHO
298 
299 #endif // DISTRHO_UI_HPP_INCLUDED
300