1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2019 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 current sample rate used in plugin processing.
86       @see sampleRateChanged(double)
87     */
88     double getSampleRate() const noexcept;
89 
90    /**
91       editParameter.
92 
93       Touch/pressed-down event.
94       Lets the host know the user is tweaking a parameter.
95       Required in some hosts to record automation.
96     */
97     void editParameter(uint32_t index, bool started);
98 
99    /**
100       setParameterValue.
101 
102       Change a parameter value in the Plugin.
103     */
104     void setParameterValue(uint32_t index, float value);
105 
106 #if DISTRHO_PLUGIN_WANT_STATE
107    /**
108       setState.
109       @TODO Document this.
110     */
111     void setState(const char* key, const char* value);
112 #endif
113 
114 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
115    /**
116       sendNote.
117       @TODO Document this.
118       @note Work in progress. Implemented for DSSI and LV2 formats.
119     */
120     void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
121 #endif
122 
123 #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
124    /* --------------------------------------------------------------------------------------------------------
125     * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */
126 
127    /**
128       getPluginInstancePointer.
129       @TODO Document this.
130     */
131     void* getPluginInstancePointer() const noexcept;
132 #endif
133 
134 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
135    /* --------------------------------------------------------------------------------------------------------
136     * External UI helpers */
137 
138    /**
139       Get the bundle path that will be used for the next UI.
140       @note: This function is only valid during createUI(),
141              it will return null when called from anywhere else.
142     */
143     static const char* getNextBundlePath() noexcept;
144 
145    /**
146       Get the scale factor that will be used for the next UI.
147       @note: This function is only valid during createUI(),
148              it will return 1.0 when called from anywhere else.
149     */
150     static double getNextScaleFactor() noexcept;
151 
152 # if DISTRHO_PLUGIN_HAS_EMBED_UI
153    /**
154       Get the Window Id that will be used for the next created window.
155       @note: This function is only valid during createUI(),
156              it will return 0 when called from anywhere else.
157     */
158     static uintptr_t getNextWindowId() noexcept;
159 # endif
160 #endif
161 
162 protected:
163    /* --------------------------------------------------------------------------------------------------------
164     * DSP/Plugin Callbacks */
165 
166    /**
167       A parameter has changed on the plugin side.@n
168       This is called by the host to inform the UI about parameter changes.
169     */
170     virtual void parameterChanged(uint32_t index, float value) = 0;
171 
172 #if DISTRHO_PLUGIN_WANT_PROGRAMS
173    /**
174       A program has been loaded on the plugin side.@n
175       This is called by the host to inform the UI about program changes.
176     */
177     virtual void programLoaded(uint32_t index) = 0;
178 #endif
179 
180 #if DISTRHO_PLUGIN_WANT_STATE
181    /**
182       A state has changed on the plugin side.@n
183       This is called by the host to inform the UI about state changes.
184     */
185     virtual void stateChanged(const char* key, const char* value) = 0;
186 #endif
187 
188    /* --------------------------------------------------------------------------------------------------------
189     * DSP/Plugin Callbacks (optional) */
190 
191    /**
192       Optional callback to inform the UI about a sample rate change on the plugin side.
193       @see getSampleRate()
194     */
195     virtual void sampleRateChanged(double newSampleRate);
196 
197 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
198    /* --------------------------------------------------------------------------------------------------------
199     * UI Callbacks (optional) */
200 
201    /**
202       uiIdle.
203       @TODO Document this.
204     */
uiIdle()205     virtual void uiIdle() {}
206 
207 # ifndef DGL_FILE_BROWSER_DISABLED
208    /**
209       File browser selected function.
210       @see Window::fileBrowserSelected(const char*)
211     */
212     virtual void uiFileBrowserSelected(const char* filename);
213 # endif
214 
215    /**
216       OpenGL window reshape function, called when parent window is resized.
217       You can reimplement this function for a custom OpenGL state.
218       @see Window::onReshape(uint,uint)
219     */
220     virtual void uiReshape(uint width, uint height);
221 
222    /* --------------------------------------------------------------------------------------------------------
223     * UI Resize Handling, internal */
224 
225    /**
226       OpenGL widget resize function, called when the widget is resized.
227       This is overriden here so the host knows when the UI is resized by you.
228       @see Widget::onResize(const ResizeEvent&)
229     */
230     void onResize(const ResizeEvent& ev) override;
231 #endif
232 
233     // -------------------------------------------------------------------------------------------------------
234 
235 private:
236     struct PrivateData;
237     PrivateData* const pData;
238     friend class UIExporter;
239     friend class UIExporterWindow;
240 
241 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
242     // these should not be used
setAbsoluteX(int) const243     void setAbsoluteX(int) const noexcept {}
setAbsoluteY(int) const244     void setAbsoluteY(int) const noexcept {}
setAbsolutePos(int,int) const245     void setAbsolutePos(int, int) const noexcept {}
setAbsolutePos(const DGL_NAMESPACE::Point<int> &) const246     void setAbsolutePos(const DGL_NAMESPACE::Point<int>&) const noexcept {}
247 #endif
248 
249     DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
250 };
251 
252 /** @} */
253 
254 /* ------------------------------------------------------------------------------------------------------------
255  * Create UI, entry point */
256 
257 /**
258    @addtogroup EntryPoints
259    @{
260  */
261 
262 /**
263    createUI.
264    @TODO Document this.
265  */
266 extern UI* createUI();
267 
268 /** @} */
269 
270 // -----------------------------------------------------------------------------------------------------------
271 
272 END_NAMESPACE_DISTRHO
273 
274 #endif // DISTRHO_UI_HPP_INCLUDED
275