ardour
au_pluginui.mm
Go to the documentation of this file.
1 #undef Marker
2 #define Marker FuckYouAppleAndYourLackOfNameSpaces
3 
4 #include <gtkmm/button.h>
5 #include <gdk/gdkquartz.h>
6 
7 #include "pbd/convert.h"
8 #include "pbd/error.h"
9 
10 #include "ardour/audio_unit.h"
11 #include "ardour/debug.h"
12 #include "ardour/plugin_insert.h"
13 
14 #undef check // stupid gtk, stupid apple
15 
16 #include <gtkmm2ext/utils.h>
17 
18 #include "au_pluginui.h"
19 #include "gui_thread.h"
20 
21 #include "appleutility/CAAudioUnit.h"
22 #include "appleutility/CAComponent.h"
23 
24 #import <AudioUnit/AUCocoaUIView.h>
25 #import <CoreAudioKit/AUGenericView.h>
26 
27 #undef Marker
28 
29 #include "keyboard.h"
30 #include "utils.h"
31 #include "public_editor.h"
32 #include "i18n.h"
33 
34 using namespace ARDOUR;
35 using namespace Gtk;
36 using namespace Gtkmm2ext;
37 using namespace std;
38 using namespace PBD;
39 
41 
42 static const gchar* _automation_mode_strings[] = {
43  X_("Manual"),
44  X_("Play"),
45  X_("Write"),
46  X_("Touch"),
47  0
48 };
49 
50 static void
51 dump_view_tree (NSView* view, int depth)
52 {
53  NSArray* subviews = [view subviews];
54  unsigned long cnt = [subviews count];
55 
56  for (int d = 0; d < depth; d++) {
57  cerr << '\t';
58  }
59  NSRect frame = [view frame];
60  cerr << " view @ " << frame.origin.x << ", " << frame.origin.y
61  << ' ' << frame.size.width << " x " << frame.size.height
62  << endl;
63 
64  for (unsigned long i = 0; i < cnt; ++i) {
65  NSView* subview = [subviews objectAtIndex:i];
66  dump_view_tree (subview, depth+1);
67  }
68 }
69 
70 @implementation NotificationObject
71 
72 - (NotificationObject*) initWithPluginUI: (AUPluginUI*) apluginui andCocoaParent: (NSWindow*) cp andTopLevelParent: (NSWindow*) tlp
73 {
74  self = [ super init ];
75 
76  if (self) {
77  plugin_ui = apluginui;
78  top_level_parent = tlp;
79 
80  if (cp) {
81  cocoa_parent = cp;
82 
83  [[NSNotificationCenter defaultCenter] addObserver:self
84  selector:@selector(cocoaParentActivationHandler:)
85  name:NSWindowDidBecomeMainNotification
86  object:NULL];
87 
88  [[NSNotificationCenter defaultCenter] addObserver:self
89  selector:@selector(cocoaParentBecameKeyHandler:)
90  name:NSWindowDidBecomeKeyNotification
91  object:NULL];
92  }
93  }
94 
95  return self;
96 }
97 
98 - (void)cocoaParentActivationHandler:(NSNotification *)notification
99 {
100  NSWindow* notification_window = (NSWindow *)[notification object];
101 
102  if (top_level_parent == notification_window || cocoa_parent == notification_window) {
103  if ([notification_window isMainWindow]) {
104  plugin_ui->activate();
105  } else {
107  }
108  }
109 }
110 
111 - (void)cocoaParentBecameKeyHandler:(NSNotification *)notification
112 {
113  NSWindow* notification_window = (NSWindow *)[notification object];
114 
115  if (top_level_parent == notification_window || cocoa_parent == notification_window) {
116  if ([notification_window isKeyWindow]) {
117  plugin_ui->activate();
118  } else {
120  }
121  }
122 }
123 
124 - (void)auViewResized:(NSNotification *)notification
125 {
126  (void) notification; // stop complaints about unusued argument
128 }
129 
130 @end
131 
133  : PlugUIBase (insert)
134  , automation_mode_label (_("Automation"))
135  , preset_label (_("Presets"))
136 
137 {
138  if (automation_mode_strings.empty()) {
140  }
141 
143  automation_mode_selector.set_active_text (automation_mode_strings.front());
144 
145  if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) {
146  error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg;
147  throw failed_constructor ();
148  }
149 
150  /* stuff some stuff into the top of the window */
151 
152  HBox* smaller_hbox = manage (new HBox);
153 
154  smaller_hbox->set_spacing (6);
155  smaller_hbox->pack_start (preset_label, false, false, 4);
156  smaller_hbox->pack_start (_preset_modified, false, false);
157  smaller_hbox->pack_start (_preset_combo, false, false);
158  smaller_hbox->pack_start (add_button, false, false);
159 #if 0
160  /* Ardour does not currently allow to overwrite existing presets
161  * see save_property_list() in audio_unit.cc
162  */
163  smaller_hbox->pack_start (save_button, false, false);
164 #endif
165 #if 0
166  /* one day these might be useful with an AU plugin, but not yet */
167  smaller_hbox->pack_start (automation_mode_label, false, false);
168  smaller_hbox->pack_start (automation_mode_selector, false, false);
169 #endif
170  smaller_hbox->pack_start (reset_button, false, false);
171  smaller_hbox->pack_start (bypass_button, false, true);
172 
173  VBox* v1_box = manage (new VBox);
174  VBox* v2_box = manage (new VBox);
175 
176  v1_box->pack_start (*smaller_hbox, false, true);
177  v2_box->pack_start (focus_button, false, true);
178 
179  top_box.set_homogeneous (false);
180  top_box.set_spacing (6);
181  top_box.set_border_width (6);
182 
183  top_box.pack_end (*v2_box, false, false);
184  top_box.pack_end (*v1_box, false, false);
185 
186  set_spacing (6);
187  pack_start (top_box, false, false);
188  pack_start (low_box, false, false);
189 
190  preset_label.show ();
191  _preset_combo.show ();
192  automation_mode_label.show ();
193  automation_mode_selector.show ();
194  bypass_button.show ();
195  top_box.show ();
196  low_box.show ();
197 
198  cocoa_parent = 0;
199  cocoa_window = 0;
200 
201 #ifdef WITH_CARBON
202  _activating_from_app = false;
203  _notify = 0;
204  au_view = 0;
205  editView = 0;
206  carbon_window = 0;
207 #endif
208 
209  /* prefer cocoa, fall back to cocoa, but use carbon if its there */
210 
211  if (test_cocoa_view_support()) {
213 #ifdef WITH_CARBON
214  } else if (test_carbon_view_support()) {
216 #endif
217  } else {
219  }
220 
221  low_box.add_events(Gdk::VISIBILITY_NOTIFY_MASK);
222 
223  low_box.signal_realize().connect (mem_fun (this, &AUPluginUI::lower_box_realized));
224  low_box.signal_visibility_notify_event ().connect (mem_fun (this, &AUPluginUI::lower_box_visibility_notify));
225 }
226 
228 {
229  if (_notify) {
230  [[NSNotificationCenter defaultCenter] removeObserver:_notify];
231  }
232 
233  if (cocoa_parent) {
234  NSWindow* win = get_nswindow();
235  [win removeChildWindow:cocoa_parent];
236  }
237 
238 #ifdef WITH_CARBON
239  if (carbon_window) {
240  /* not parented, just overlaid on top of our window */
241  DisposeWindow (carbon_window);
242  }
243 #endif
244 
245  if (editView) {
246  CloseComponent (editView);
247  }
248 
249  if (au_view) {
250  /* remove whatever we packed into low_box so that GTK doesn't
251  mess with it.
252  */
253 
254  [au_view removeFromSuperview];
255  }
256 }
257 
258 bool
260 {
261 #ifdef WITH_CARBON
262  bool ret = false;
263 
264  carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType;
265  carbon_descriptor.componentSubType = 'gnrc';
266  carbon_descriptor.componentManufacturer = 'appl';
267  carbon_descriptor.componentFlags = 0;
268  carbon_descriptor.componentFlagsMask = 0;
269 
270  OSStatus err;
271 
272  // ask the AU for its first editor component
273  UInt32 propertySize;
274  err = AudioUnitGetPropertyInfo(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, &propertySize, NULL);
275  if (!err) {
276  int nEditors = propertySize / sizeof(ComponentDescription);
277  ComponentDescription *editors = new ComponentDescription[nEditors];
278  err = AudioUnitGetProperty(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, editors, &propertySize);
279  if (!err) {
280  // just pick the first one for now
281  carbon_descriptor = editors[0];
282  ret = true;
283  }
284  delete[] editors;
285  }
286 
287  return ret;
288 #else
289  return false;
290 #endif
291 }
292 
293 bool
295 {
296  UInt32 dataSize = 0;
297  Boolean isWritable = 0;
298  OSStatus err = AudioUnitGetPropertyInfo(*au->get_au(),
299  kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
300  0, &dataSize, &isWritable);
301 
302  return dataSize > 0 && err == noErr;
303 }
304 
305 bool
307 {
308  if([pluginClass conformsToProtocol: @protocol(AUCocoaUIBase)]) {
309  if([pluginClass instancesRespondToSelector: @selector(interfaceVersion)] &&
310  [pluginClass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) {
311  return true;
312  }
313  }
314  return false;
315 }
316 
317 int
319 {
320  bool wasAbleToLoadCustomView = false;
321  AudioUnitCocoaViewInfo* cocoaViewInfo = NULL;
322  UInt32 numberOfClasses = 0;
323  UInt32 dataSize;
324  Boolean isWritable;
325  NSString* factoryClassName = 0;
326  NSURL* CocoaViewBundlePath = NULL;
327 
328  OSStatus result = AudioUnitGetPropertyInfo (*au->get_au(),
329  kAudioUnitProperty_CocoaUI,
330  kAudioUnitScope_Global,
331  0,
332  &dataSize,
333  &isWritable );
334 
335  numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
336 
337  // Does view have custom Cocoa UI?
338 
339  if ((result == noErr) && (numberOfClasses > 0) ) {
340 
342  string_compose ( "based on %1, there are %2 cocoa UI classes\n", dataSize, numberOfClasses));
343 
344  cocoaViewInfo = (AudioUnitCocoaViewInfo *)malloc(dataSize);
345 
346  if(AudioUnitGetProperty(*au->get_au(),
347  kAudioUnitProperty_CocoaUI,
348  kAudioUnitScope_Global,
349  0,
350  cocoaViewInfo,
351  &dataSize) == noErr) {
352 
353  CocoaViewBundlePath = (NSURL *)cocoaViewInfo->mCocoaAUViewBundleLocation;
354 
355  // we only take the first view in this example.
356  factoryClassName = (NSString *)cocoaViewInfo->mCocoaAUViewClass[0];
357 
358  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("the factory name is %1 bundle is %2\n",
359  [factoryClassName UTF8String], CocoaViewBundlePath));
360 
361  } else {
362 
363  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("No cocoaUI property cocoaViewInfo = %1\n", cocoaViewInfo));
364 
365  if (cocoaViewInfo != NULL) {
366  free (cocoaViewInfo);
367  cocoaViewInfo = NULL;
368  }
369  }
370  }
371 
372  // [A] Show custom UI if view has it
373 
374  if (CocoaViewBundlePath && factoryClassName) {
375  NSBundle *viewBundle = [NSBundle bundleWithPath:[CocoaViewBundlePath path]];
376 
377  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("tried to create bundle, result = %1\n", viewBundle));
378 
379  if (viewBundle == NULL) {
380  error << _("AUPluginUI: error loading AU view's bundle") << endmsg;
381  return -1;
382  } else {
383  Class factoryClass = [viewBundle classNamed:factoryClassName];
384  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("tried to create factory class, result = %1\n", factoryClass));
385  if (!factoryClass) {
386  error << _("AUPluginUI: error getting AU view's factory class from bundle") << endmsg;
387  return -1;
388  }
389 
390  // make sure 'factoryClass' implements the AUCocoaUIBase protocol
391  if (!plugin_class_valid (factoryClass)) {
392  error << _("AUPluginUI: U view's factory class does not properly implement the AUCocoaUIBase protocol") << endmsg;
393  return -1;
394  }
395  // make a factory
396  id factory = [[[factoryClass alloc] init] autorelease];
397  if (factory == NULL) {
398  error << _("AUPluginUI: Could not create an instance of the AU view factory") << endmsg;
399  return -1;
400  }
401 
402  DEBUG_TRACE (DEBUG::AudioUnits, "got a factory instance\n");
403 
404  // make a view
405  au_view = [factory uiViewForAudioUnit:*au->get_au() withSize:NSZeroSize];
406 
407  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("view created @ %1\n", au_view));
408 
409  // cleanup
410  [CocoaViewBundlePath release];
411  if (cocoaViewInfo) {
412  UInt32 i;
413  for (i = 0; i < numberOfClasses; i++)
414  CFRelease(cocoaViewInfo->mCocoaAUViewClass[i]);
415 
416  free (cocoaViewInfo);
417  }
418  wasAbleToLoadCustomView = true;
419  }
420  }
421 
422  if (!wasAbleToLoadCustomView) {
423  // load generic Cocoa view
424  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("Loading generic view using %1 -> %2\n", au,
425  au->get_au()));
426  au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()];
427  DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("view created @ %1\n", au_view));
428  [(AUGenericView *)au_view setShowsExpertParameters:1];
429  }
430 
431  // Get the initial size of the new AU View's frame
432 
433  NSRect rect = [au_view frame];
434  prefheight = rect.size.height;
435  prefwidth = rect.size.width;
436  low_box.set_size_request (rect.size.width, rect.size.height);
437 
438  return 0;
439 }
440 
441 void
443 {
444  NSWindow* window = get_nswindow ();
445  NSRect windowFrame= [window frame];
446  NSRect new_frame = [au_view frame];
447 
448  float dy = last_au_frame.size.height - new_frame.size.height;
449  float dx = last_au_frame.size.width - new_frame.size.width;
450 
451  windowFrame.origin.y += dy;
452  windowFrame.origin.x += dx;
453  windowFrame.size.height -= dy;
454  windowFrame.size.width -= dx;
455 
456  [[NSNotificationCenter defaultCenter] removeObserver:_notify
457  name:NSViewFrameDidChangeNotification
458  object:au_view];
459 
460  NSUInteger old_auto_resize = [au_view autoresizingMask];
461 
462  [au_view setAutoresizingMask:NSViewNotSizable];
463  [window setFrame:windowFrame display:1];
464 
465  /* Some stupid AU Views change the origin of the original AU View
466  when they are resized (I'm looking at you AUSampler). If the origin
467  has been moved, move it back.
468  */
469 
470  if (last_au_frame.origin.x != new_frame.origin.x ||
471  last_au_frame.origin.y != new_frame.origin.y) {
472  new_frame.origin = last_au_frame.origin;
473  [au_view setFrame:new_frame];
474  /* also be sure to redraw the topbox because this can
475  also go wrong.
476  */
477  top_box.queue_draw ();
478  }
479 
480  [au_view setAutoresizingMask:old_auto_resize];
481 
482  [[NSNotificationCenter defaultCenter] addObserver:_notify
483  selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification
484  object:au_view];
485 
486  last_au_frame = new_frame;
487 }
488 
489 int
491 {
492 #ifdef WITH_CARBON
493  OSStatus err;
494  ControlRef root_control;
495 
496  Component editComponent = FindNextComponent(NULL, &carbon_descriptor);
497 
498  OpenAComponent(editComponent, &editView);
499  if (!editView) {
500  error << _("AU Carbon view: cannot open AU Component") << endmsg;
501  return -1;
502  }
503 
504  Rect r = { 100, 100, 100, 100 };
505  WindowAttributes attr = WindowAttributes (kWindowStandardHandlerAttribute |
506  kWindowCompositingAttribute|
507  kWindowNoShadowAttribute|
508  kWindowNoTitleBarAttribute);
509 
510  if ((err = CreateNewWindow(kUtilityWindowClass, attr, &r, &carbon_window)) != noErr) {
511  error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
512  CloseComponent (editView);
513  return -1;
514  }
515 
516  if ((err = GetRootControl(carbon_window, &root_control)) != noErr) {
517  error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg;
518  DisposeWindow (carbon_window);
519  CloseComponent (editView);
520  return -1;
521  }
522 
523  ControlRef viewPane;
524  Float32Point location = { 0.0, 0.0 };
525  Float32Point size = { 0.0, 0.0 } ;
526 
527  if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) {
528  error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg;
529  DisposeWindow (carbon_window);
530  CloseComponent (editView);
531  return -1;
532  }
533 
534  // resize window
535 
536  Rect bounds;
537  GetControlBounds(viewPane, &bounds);
538  size.x = bounds.right-bounds.left;
539  size.y = bounds.bottom-bounds.top;
540 
541  prefwidth = (int) (size.x + 0.5);
542  prefheight = (int) (size.y + 0.5);
543 
544  SizeWindow (carbon_window, prefwidth, prefheight, true);
545  low_box.set_size_request (prefwidth, prefheight);
546 
547  return 0;
548 #else
549  error << _("AU Carbon GUI is not supported.") << endmsg;
550  return -1;
551 #endif
552 }
553 
554 NSWindow*
556 {
557  Gtk::Container* toplevel = get_toplevel();
558 
559  if (!toplevel || !toplevel->is_toplevel()) {
560  error << _("AUPluginUI: no top level window!") << endmsg;
561  return 0;
562  }
563 
564  NSWindow* true_parent = gdk_quartz_window_get_nswindow (toplevel->get_window()->gobj());
565 
566  if (!true_parent) {
567  error << _("AUPluginUI: no top level window!") << endmsg;
568  return 0;
569  }
570 
571  return true_parent;
572 }
573 
574 void
576 {
577 #ifdef WITH_CARBON
578  ActivateWindow (carbon_window, TRUE);
579 #endif
580 }
581 
582 void
584 {
585 #ifdef WITH_CARBON
586  ActivateWindow (carbon_window, FALSE);
587 #endif
588 }
589 
590 int
592 {
593 #ifdef WITH_CARBON
594  NSWindow* win = get_nswindow ();
595  Rect windowStructureBoundsRect;
596 
597  if (!win) {
598  return -1;
599  }
600 
601  Gtk::Container* toplevel = get_toplevel();
602 
603  if (!toplevel || !toplevel->is_toplevel()) {
604  error << _("AUPluginUI: no top level window!") << endmsg;
605  return -1;
606  }
607 
608  /* figure out where the cocoa parent window is in carbon-coordinate space, which
609  differs from both cocoa-coordinate space and GTK-coordinate space
610  */
611 
612  GetWindowBounds((WindowRef) [win windowRef], kWindowStructureRgn, &windowStructureBoundsRect);
613 
614  /* compute how tall the title bar is, because we have to offset the position of the carbon window
615  by that much.
616  */
617 
618  NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]];
619  NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]];
620 
621  int titlebar_height = wm_frame.size.height - content_frame.size.height;
622 
623  int packing_extra = 6; // this is the total vertical packing in our top level window
624 
625  /* move into position, based on parent window position */
626  MoveWindow (carbon_window,
627  windowStructureBoundsRect.left,
628  windowStructureBoundsRect.top + titlebar_height + top_box.get_height() + packing_extra,
629  false);
630  ShowWindow (carbon_window);
631 
632  // create the cocoa window for the carbon one and make it visible
633  cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
634 
635  SetWindowActivationScope (carbon_window, kWindowActivationScopeNone);
636 
637  _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ];
638 
639  [win addChildWindow:cocoa_parent ordered:NSWindowAbove];
640  [win setAutodisplay:1]; // turn of GTK stuff for this window
641 
642  return 0;
643 #else
644  return -1;
645 #endif
646 }
647 
648 int
650 {
651  NSWindow* win = get_nswindow ();
652 
653  if (!win) {
654  return -1;
655  }
656 
657  [win setAutodisplay:1]; // turn of GTK stuff for this window
658 
659  Gtk::Container* toplevel = get_toplevel();
660 
661  if (!toplevel || !toplevel->is_toplevel()) {
662  error << _("AUPluginUI: no top level window!") << endmsg;
663  return -1;
664  }
665 
666  NSView* view = gdk_quartz_window_get_nsview (get_toplevel()->get_window()->gobj());
667  GtkRequisition a = top_box.size_request ();
668 
669  /* move the au_view down so that it doesn't overlap the top_box contents */
670 
671  const int spacing = 6; // main vbox spacing
672  const int pad = 4; // box pad
673 
674  NSPoint origin = { spacing + pad, static_cast<CGFloat> (a.height) + (2 * spacing) + pad };
675 
676  [au_view setFrameOrigin:origin];
677  [view addSubview:au_view positioned:NSWindowBelow relativeTo:NULL];
678 
679  last_au_frame = [au_view frame];
680 
681  // watch for size changes of the view
682 
683  _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:NULL andTopLevelParent:win ];
684 
685  [[NSNotificationCenter defaultCenter] addObserver:_notify
686  selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification
687  object:au_view];
688 
689  return 0;
690 }
691 
692 void
694 {
695  if (au_view) {
696  [au_view becomeFirstResponder];
697  }
698 }
699 void
701 {
702  NSEvent* nsevent = gdk_quartz_event_get_nsevent ((GdkEvent*)ev);
703 
704  if (au_view && nsevent) {
705 
706  /* filter on nsevent type here because GDK massages FlagsChanged
707  messages into GDK_KEY_{PRESS,RELEASE} but Cocoa won't
708  handle a FlagsChanged message as a keyDown or keyUp
709  */
710 
711  if ([nsevent type] == NSKeyDown) {
712  [[[au_view window] firstResponder] keyDown:nsevent];
713  } else if ([nsevent type] == NSKeyUp) {
714  [[[au_view window] firstResponder] keyUp:nsevent];
715  } else if ([nsevent type] == NSFlagsChanged) {
716  [[[au_view window] firstResponder] flagsChanged:nsevent];
717  }
718  }
719 }
720 
721 void
723 {
724  VBox::on_realize ();
725 
726  /* our windows should not have that resize indicator */
727 
728  NSWindow* win = get_nswindow ();
729  if (win) {
730  [win setShowsResizeIndicator:0];
731  }
732 }
733 
734 void
736 {
737  if (au_view) {
739  } else if (carbon_window) {
741  }
742 }
743 
744 bool
746 {
747 #ifdef WITH_CARBON
748  if (carbon_window && ev->state != GDK_VISIBILITY_UNOBSCURED) {
749  ShowWindow (carbon_window);
750  ActivateWindow (carbon_window, TRUE);
751  return true;
752  }
753 #endif
754  return false;
755 }
756 
757 void
759 {
760 #ifdef WITH_CARBON
761  if (carbon_window) {
762  HideWindow (carbon_window);
763  ActivateWindow (carbon_window, FALSE);
764  }
765 #endif
766  hide_all ();
767 
768 #if 0
769  NSArray* wins = [NSApp windows];
770  for (uint32_t i = 0; i < [wins count]; i++) {
771  id win = [wins objectAtIndex:i];
772  }
773 #endif
774 }
775 
776 bool
777 AUPluginUI::on_window_show (const string& /*title*/)
778 {
779  /* this is idempotent so just call it every time we show the window */
780 
781  gtk_widget_realize (GTK_WIDGET(low_box.gobj()));
782 
783  show_all ();
784 
785 #ifdef WITH_CARBON
786  if (carbon_window) {
787  ShowWindow (carbon_window);
788  ActivateWindow (carbon_window, TRUE);
789  }
790 #endif
791 
792  return true;
793 }
794 
795 bool
797 {
798  return false;
799 }
800 
801 bool
803 {
804  return false;
805 }
806 
807 PlugUIBase*
809 {
810  AUPluginUI* aup = new AUPluginUI (plugin_insert);
811  (*box) = aup;
812  return aup;
813 }
814 
815 
AudioUnitCarbonView editView
Definition: au_pluginui.h:122
void cocoa_view_resized()
Definition: au_pluginui.mm:442
PlugUIBase * create_au_gui(boost::shared_ptr< PluginInsert > plugin_insert, VBox **box)
Definition: au_pluginui.mm:808
NotificationObject * _notify
Definition: au_pluginui.h:126
WindowRef carbon_window
Definition: au_pluginui.h:123
static void dump_view_tree(NSView *view, int depth)
Definition: au_pluginui.mm:51
Gtk::HBox top_box
Definition: au_pluginui.h:103
int prefheight
Definition: au_pluginui.h:100
int create_cocoa_view()
Definition: au_pluginui.mm:318
void activate()
Definition: au_pluginui.mm:575
Definition: ardour_ui.h:130
AUPluginUI(boost::shared_ptr< ARDOUR::PluginInsert >)
Definition: au_pluginui.mm:132
ArdourDropdown _preset_combo
Definition: plugin_ui.h:119
int parent_cocoa_window()
Definition: au_pluginui.mm:649
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
NSWindow * get_nswindow()
Definition: au_pluginui.mm:555
NSWindow * top_level_parent
Definition: au_pluginui.h:64
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
LIBGTKMM2EXT_API void set_popdown_strings(Gtk::ComboBoxText &, const std::vector< std::string > &)
NSWindow * cocoa_parent
Definition: au_pluginui.h:120
boost::shared_ptr< Plugin > plugin(uint32_t num=0) const
void on_realize()
Definition: au_pluginui.mm:722
bool test_cocoa_view_support()
Definition: au_pluginui.mm:294
ArdourButton bypass_button
Definition: plugin_ui.h:131
#define origin
void grab_focus()
Definition: au_pluginui.mm:693
AUPluginUI * plugin_ui
Definition: au_pluginui.h:62
#define _(Text)
Definition: i18n.h:11
static std::vector< std::string > automation_mode_strings
Definition: au_pluginui.h:110
void on_window_hide()
Definition: au_pluginui.mm:758
NSWindow * cocoa_parent
Definition: au_pluginui.h:63
#define X_(Text)
Definition: i18n.h:13
Gtk::EventBox focus_button
Definition: plugin_ui.h:133
bool _activating_from_app
Definition: au_pluginui.h:125
Gtk::EventBox low_box
Definition: au_pluginui.h:104
Definition: amp.h:29
boost::shared_ptr< ARDOUR::AUPlugin > au
Definition: au_pluginui.h:99
NSView * au_view
Definition: au_pluginui.h:115
ComponentDescription carbon_descriptor
Definition: au_pluginui.h:121
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
#define I18N(Array)
Definition: i18n.h:14
Gtk::Label automation_mode_label
Definition: au_pluginui.h:106
bool start_updating(GdkEventAny *)
Definition: au_pluginui.mm:796
bool lower_box_visibility_notify(GdkEventVisibility *)
Definition: au_pluginui.mm:745
static const gchar * _automation_mode_strings[]
Definition: au_pluginui.mm:42
NSWindow * cocoa_window
Definition: au_pluginui.h:114
bool stop_updating(GdkEventAny *)
Definition: au_pluginui.mm:802
boost::shared_ptr< CAAudioUnit > get_au()
Definition: audio_unit.h:116
void forward_key_event(GdkEventKey *)
Definition: au_pluginui.mm:700
ArdourButton add_button
Definition: plugin_ui.h:123
bool plugin_class_valid(Class pluginClass)
Definition: au_pluginui.mm:306
void deactivate()
Definition: au_pluginui.mm:583
Gtk::Label preset_label
Definition: au_pluginui.h:108
int parent_carbon_window()
Definition: au_pluginui.mm:591
Definition: debug.h:30
LIBARDOUR_API uint64_t AudioUnits
Definition: debug.cc:54
Gtk::ComboBoxText automation_mode_selector
Definition: au_pluginui.h:107
int create_carbon_view()
Definition: au_pluginui.mm:490
Gtk::Label _preset_modified
Definition: plugin_ui.h:121
NSRect last_au_frame
Definition: au_pluginui.h:116
bool on_window_show(const std::string &)
Definition: au_pluginui.mm:777
ArdourButton reset_button
Definition: plugin_ui.h:129
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
bool test_carbon_view_support()
Definition: au_pluginui.mm:259
ArdourButton save_button
Definition: plugin_ui.h:125
void lower_box_realized()
Definition: au_pluginui.mm:735