@@ -16,6 +16,7 @@ use api::consts::*;
16
16
use api:: { self , AEffect , PluginFlags , PluginMain , Supported , TimeInfo } ;
17
17
use buffer:: AudioBuffer ;
18
18
use channels:: ChannelInfo ;
19
+ use editor:: { Editor , Rect } ;
19
20
use interfaces;
20
21
use plugin:: { self , Category , Info , Plugin , PluginParameters } ;
21
22
@@ -283,6 +284,7 @@ pub struct PluginInstance {
283
284
params : Arc < PluginParametersInstance > ,
284
285
lib : Arc < Library > ,
285
286
info : Info ,
287
+ is_editor_active : bool ,
286
288
}
287
289
288
290
struct PluginParametersInstance {
@@ -297,6 +299,70 @@ impl Drop for PluginInstance {
297
299
}
298
300
}
299
301
302
+ /// The editor of an externally loaded VST plugin.
303
+ struct EditorInstance {
304
+ params : Arc < PluginParametersInstance > ,
305
+ is_open : bool ,
306
+ }
307
+
308
+ impl EditorInstance {
309
+ fn get_rect ( & self ) -> Option < Rect > {
310
+ let mut rect: * mut Rect = std:: ptr:: null_mut ( ) ;
311
+ let rect_ptr: * mut * mut Rect = & mut rect;
312
+
313
+ let result = self . params . dispatch ( plugin:: OpCode :: EditorGetRect , 0 , 0 , rect_ptr as * mut c_void , 0.0 ) ;
314
+
315
+ if result == 0 || rect. is_null ( ) {
316
+ return None ;
317
+ }
318
+ Some ( unsafe { * rect } ) // TODO: Who owns rect? Who should free the memory?
319
+ }
320
+ }
321
+
322
+ impl Editor for EditorInstance {
323
+ fn size ( & self ) -> ( i32 , i32 ) {
324
+ // Assuming coordinate origins from top-left
325
+ match self . get_rect ( ) {
326
+ None => ( 0 , 0 ) ,
327
+ Some ( rect) => (
328
+ ( rect. right - rect. left ) as i32 ,
329
+ ( rect. bottom - rect. top ) as i32
330
+ ) ,
331
+ }
332
+ }
333
+
334
+ fn position ( & self ) -> ( i32 , i32 ) {
335
+ // Assuming coordinate origins from top-left
336
+ match self . get_rect ( ) {
337
+ None => ( 0 , 0 ) ,
338
+ Some ( rect) => (
339
+ rect. left as i32 ,
340
+ rect. top as i32
341
+ ) ,
342
+ }
343
+ }
344
+
345
+ fn close ( & mut self ) {
346
+ self . params . dispatch ( plugin:: OpCode :: EditorClose , 0 , 0 , ptr:: null_mut ( ) , 0.0 ) ;
347
+ self . is_open = false ;
348
+ }
349
+
350
+ fn open ( & mut self , parent : * mut c_void ) -> bool {
351
+ let result = self . params . dispatch ( plugin:: OpCode :: EditorOpen , 0 , 0 , parent, 0.0 ) ;
352
+
353
+ let opened = result == 1 ;
354
+ if opened {
355
+ self . is_open = true ;
356
+ }
357
+
358
+ opened
359
+ }
360
+
361
+ fn is_open ( & mut self ) -> bool {
362
+ self . is_open
363
+ }
364
+ }
365
+
300
366
impl < T : Host > PluginLoader < T > {
301
367
/// Load a plugin at the given path with the given host.
302
368
///
@@ -406,6 +472,7 @@ impl PluginInstance {
406
472
params,
407
473
lib,
408
474
info : Default :: default ( ) ,
475
+ is_editor_active : false ,
409
476
} ;
410
477
411
478
unsafe {
@@ -588,6 +655,18 @@ impl Plugin for PluginInstance {
588
655
fn get_parameter_object ( & mut self ) -> Arc < dyn PluginParameters > {
589
656
Arc :: clone ( & self . params ) as Arc < dyn PluginParameters >
590
657
}
658
+
659
+ fn get_editor ( & mut self ) -> Option < Box < dyn Editor > > {
660
+ if self . is_editor_active
661
+ {
662
+ // An editor is already active, the caller should be using the active editor instead of
663
+ // requesting for a new one.
664
+ return None ;
665
+ }
666
+
667
+ self . is_editor_active = true ;
668
+ Some ( Box :: new ( EditorInstance { params : self . params . clone ( ) , is_open : false } ) )
669
+ }
591
670
}
592
671
593
672
impl PluginParameters for PluginParametersInstance {
0 commit comments