DISTRHO Plugin Framework
DistrhoUI.hpp
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_HPP_INCLUDED
18 #define DISTRHO_UI_HPP_INCLUDED
19 
20 #include "extra/LeakDetector.hpp"
21 #include "src/DistrhoPluginChecks.h"
22 
23 #ifdef DGL_CAIRO
24 # include "Cairo.hpp"
25 #endif
26 #ifdef DGL_OPENGL
27 # include "OpenGL.hpp"
28 #endif
29 #ifdef DGL_VULKAN
30 # include "Vulkan.hpp"
31 #endif
32 
33 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
34 # include "../dgl/Base.hpp"
35 # include "extra/ExternalWindow.hpp"
36 typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget;
37 #elif DISTRHO_UI_USE_CUSTOM
38 # include DISTRHO_UI_CUSTOM_INCLUDE_PATH
39 typedef DISTRHO_UI_CUSTOM_WIDGET_TYPE UIWidget;
40 #elif DISTRHO_UI_USE_CAIRO
41 # include "../dgl/Cairo.hpp"
42 typedef DGL_NAMESPACE::CairoTopLevelWidget UIWidget;
43 #elif DISTRHO_UI_USE_NANOVG
44 # include "../dgl/NanoVG.hpp"
45 typedef DGL_NAMESPACE::NanoTopLevelWidget UIWidget;
46 #else
47 # include "../dgl/TopLevelWidget.hpp"
48 typedef DGL_NAMESPACE::TopLevelWidget UIWidget;
49 #endif
50 
51 START_NAMESPACE_DISTRHO
52 
53 /* ------------------------------------------------------------------------------------------------------------
54  * DPF UI */
55 
56 /**
57  @addtogroup MainClasses
58  @{
59  */
60 
61 /**
62  DPF UI class from where UI instances are created.
63 
64  @note You must call setSize during construction,
65  @TODO Detailed information about this class.
66  */
67 class UI : public UIWidget
68 {
69 public:
70  /**
71  UI class constructor.
72  The UI should be initialized to a default state that matches the plugin side.
73  */
74  UI(uint width = 0, uint height = 0);
75 
76  /**
77  Destructor.
78  */
79  virtual ~UI();
80 
81  /* --------------------------------------------------------------------------------------------------------
82  * Host state */
83 
84  /**
85  Check if this UI window is resizable (by the user or window manager).
86  There are situations where an UI supports resizing but the plugin host does not, so this could return false.
87 
88  You might want to add a resize handle for such cases, so the user is still allowed to resize the window.
89  (programatically resizing a window is always possible, but the same is not true for the window manager)
90  */
91  bool isResizable() const noexcept;
92 
93  /**
94  Get the color used for UI background (i.e. window color) in RGBA format.
95  Returns 0 by default, in case of error or lack of host support.
96 
97  The following example code can be use to extract individual colors:
98  ```
99  const int red = (bgColor >> 24) & 0xff;
100  const int green = (bgColor >> 16) & 0xff;
101  const int blue = (bgColor >> 8) & 0xff;
102  ```
103  */
104  uint getBackgroundColor() const noexcept;
105 
106  /**
107  Get the color used for UI foreground (i.e. text color) in RGBA format.
108  Returns 0xffffffff by default, in case of error or lack of host support.
109 
110  The following example code can be use to extract individual colors:
111  ```
112  const int red = (fgColor >> 24) & 0xff;
113  const int green = (fgColor >> 16) & 0xff;
114  const int blue = (fgColor >> 8) & 0xff;
115  ```
116  */
117  uint getForegroundColor() const noexcept;
118 
119  /**
120  Get the current sample rate used in plugin processing.
121  @see sampleRateChanged(double)
122  */
123  double getSampleRate() const noexcept;
124 
125  /**
126  editParameter.
127 
128  Touch/pressed-down event.
129  Lets the host know the user is tweaking a parameter.
130  Required in some hosts to record automation.
131  */
132  void editParameter(uint32_t index, bool started);
133 
134  /**
135  setParameterValue.
136 
137  Change a parameter value in the Plugin.
138  */
139  void setParameterValue(uint32_t index, float value);
140 
141 #if DISTRHO_PLUGIN_WANT_STATE
142  /**
143  setState.
144  @TODO Document this.
145  */
146  void setState(const char* key, const char* value);
147 #endif
148 
149 #if DISTRHO_PLUGIN_WANT_STATEFILES
150  /**
151  Request a new file from the host, matching the properties of a state key.@n
152  This will use the native host file browser if available, otherwise a DPF built-in file browser is used.@n
153  Response will be sent asynchronously to stateChanged, with the matching key and the new file as the value.@n
154  It is not possible to know if the action was cancelled by the user.
155 
156  @return Success if a file-browser was opened, otherwise false.
157  @note You cannot request more than one file at a time.
158  */
159  bool requestStateFile(const char* key);
160 #endif
161 
162 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
163  /**
164  Send a single MIDI note from the UI to the plugin DSP side.@n
165  A note with zero velocity will be sent as note-off (MIDI 0x80), otherwise note-on (MIDI 0x90).
166  */
167  void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
168 #endif
169 
170 #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
171  /* --------------------------------------------------------------------------------------------------------
172  * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */
173 
174  /**
175  getPluginInstancePointer.
176  @TODO Document this.
177  */
178  void* getPluginInstancePointer() const noexcept;
179 #endif
180 
181 #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
182  /* --------------------------------------------------------------------------------------------------------
183  * External UI helpers */
184 
185  /**
186  Get the bundle path that will be used for the next UI.
187  @note: This function is only valid during createUI(),
188  it will return null when called from anywhere else.
189  */
190  static const char* getNextBundlePath() noexcept;
191 
192  /**
193  Get the scale factor that will be used for the next UI.
194  @note: This function is only valid during createUI(),
195  it will return 1.0 when called from anywhere else.
196  */
197  static double getNextScaleFactor() noexcept;
198 
199 # if DISTRHO_PLUGIN_HAS_EMBED_UI
200  /**
201  Get the Window Id that will be used for the next created window.
202  @note: This function is only valid during createUI(),
203  it will return 0 when called from anywhere else.
204  */
205  static uintptr_t getNextWindowId() noexcept;
206 # endif
207 #endif
208 
209 protected:
210  /* --------------------------------------------------------------------------------------------------------
211  * DSP/Plugin Callbacks */
212 
213  /**
214  A parameter has changed on the plugin side.@n
215  This is called by the host to inform the UI about parameter changes.
216  */
217  virtual void parameterChanged(uint32_t index, float value) = 0;
218 
219 #if DISTRHO_PLUGIN_WANT_PROGRAMS
220  /**
221  A program has been loaded on the plugin side.@n
222  This is called by the host to inform the UI about program changes.
223  */
224  virtual void programLoaded(uint32_t index) = 0;
225 #endif
226 
227 #if DISTRHO_PLUGIN_WANT_STATE
228  /**
229  A state has changed on the plugin side.@n
230  This is called by the host to inform the UI about state changes.
231  */
232  virtual void stateChanged(const char* key, const char* value) = 0;
233 #endif
234 
235  /* --------------------------------------------------------------------------------------------------------
236  * DSP/Plugin Callbacks (optional) */
237 
238  /**
239  Optional callback to inform the UI about a sample rate change on the plugin side.
240  @see getSampleRate()
241  */
242  virtual void sampleRateChanged(double newSampleRate);
243 
244 #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
245  /* --------------------------------------------------------------------------------------------------------
246  * UI Callbacks (optional) */
247 
248  /**
249  UI idle function, called to give idle time to the plugin UI directly from the host.
250  This is called right after OS event handling and Window idle events (within the same cycle).
251  There are no guarantees in terms of timing.
252  @see addIdleCallback(IdleCallback*, uint).
253  */
254  virtual void uiIdle() {}
255 
256  /**
257  Windows focus function, called when the window gains or loses the keyboard focus.
258  This function is for plugin UIs to be able to override Window::onFocus(bool, CrossingMode).
259 
260  The default implementation does nothing.
261  */
262  virtual void uiFocus(bool focus, DGL_NAMESPACE::CrossingMode mode);
263 
264  /**
265  Window reshape function, called when the window is resized.
266  This function is for plugin UIs to be able to override Window::onReshape(uint, uint).
267 
268  The plugin UI size will be set right after this function.
269  The default implementation sets up drawing context where necessary.
270 
271  You should almost never need to override this function.
272  The most common exception is custom OpenGL setup, but only really needed for custom OpenGL drawing code.
273  */
274  virtual void uiReshape(uint width, uint height);
275 
276  /**
277  Window scale factor function, called when the scale factor changes.
278  This function is for plugin UIs to be able to override Window::onScaleFactorChanged(double).
279 
280  The default implementation does nothing.
281  WARNING function needs a proper name
282  */
283  virtual void uiScaleFactorChanged(double scaleFactor);
284 
285 # ifndef DGL_FILE_BROWSER_DISABLED
286  /**
287  Window file selected function, called when a path is selected by the user, as triggered by openFileBrowser().
288  This function is for plugin UIs to be able to override Window::onFileSelected(const char*).
289 
290  This action happens after the user confirms the action, so the file browser dialog will be closed at this point.
291  The default implementation does nothing.
292 
293  If you need to use files as plugin state, please setup and use DISTRHO_PLUGIN_WANT_STATEFILES instead.
294  */
295  virtual void uiFileBrowserSelected(const char* filename);
296 # endif
297 
298  /* --------------------------------------------------------------------------------------------------------
299  * UI Resize Handling, internal */
300 
301  /**
302  OpenGL widget resize function, called when the widget is resized.
303  This is overriden here so the host knows when the UI is resized by you.
304  @see Widget::onResize(const ResizeEvent&)
305  */
306  void onResize(const ResizeEvent& ev) override;
307 #endif
308 
309  // -------------------------------------------------------------------------------------------------------
310 
311 private:
312  struct PrivateData;
313  PrivateData* const uiData;
314  friend class PluginWindow;
315  friend class UIExporter;
316 
317  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
318 };
319 
320 /** @} */
321 
322 /* ------------------------------------------------------------------------------------------------------------
323  * Create UI, entry point */
324 
325 /**
326  @addtogroup EntryPoints
327  @{
328  */
329 
330 /**
331  createUI.
332  @TODO Document this.
333  */
334 extern UI* createUI();
335 
336 /** @} */
337 
338 // -----------------------------------------------------------------------------------------------------------
339 
340 END_NAMESPACE_DISTRHO
341 
342 #endif // DISTRHO_UI_HPP_INCLUDED
UI::getNextScaleFactor
static double getNextScaleFactor() noexcept
UI::stateChanged
virtual void stateChanged(const char *key, const char *value)=0
UI::~UI
virtual ~UI()
UI::getForegroundColor
uint getForegroundColor() const noexcept
UI::programLoaded
virtual void programLoaded(uint32_t index)=0
UI::getBackgroundColor
uint getBackgroundColor() const noexcept
UI::setParameterValue
void setParameterValue(uint32_t index, float value)
UI::isResizable
bool isResizable() const noexcept
UI
Definition: DistrhoUI.hpp:67
UI::sendNote
void sendNote(uint8_t channel, uint8_t note, uint8_t velocity)
UI::getNextBundlePath
static const char * getNextBundlePath() noexcept
UI::getSampleRate
double getSampleRate() const noexcept
UI::UI
UI(uint width=0, uint height=0)
UI::editParameter
void editParameter(uint32_t index, bool started)
DISTRHO_UI_CUSTOM_WIDGET_TYPE
#define DISTRHO_UI_CUSTOM_WIDGET_TYPE
Definition: DistrhoInfo.hpp:594
UI::sampleRateChanged
virtual void sampleRateChanged(double newSampleRate)
createUI
UI * createUI()
UI::getPluginInstancePointer
void * getPluginInstancePointer() const noexcept
UI::getNextWindowId
static uintptr_t getNextWindowId() noexcept
UI::setState
void setState(const char *key, const char *value)
UI::parameterChanged
virtual void parameterChanged(uint32_t index, float value)=0