2 #define Marker FuckYouAppleAndYourLackOfNameSpaces
4 #include <gtkmm/button.h>
5 #include <gdk/gdkquartz.h>
7 #include "pbd/convert.h"
10 #include "ardour/audio_unit.h"
11 #include "ardour/debug.h"
12 #include "ardour/plugin_insert.h"
14 #undef check // stupid gtk, stupid apple
16 #include <gtkmm2ext/utils.h>
17 #include <gtkmm2ext/window_proxy.h>
19 #include "au_pluginui.h"
20 #include "gui_thread.h"
21 #include "processor_box.h"
23 #include "CAAudioUnit.h"
24 #include "CAComponent.h"
26 #import <AudioUnit/AUCocoaUIView.h>
27 #import <CoreAudioKit/AUGenericView.h>
33 #include "public_editor.h"
37 #define ArdourCloseComponent CloseComponent
39 #define ArdourCloseComponent AudioComponentInstanceDispose
41 using namespace ARDOUR;
43 using namespace Gtkmm2ext;
47 vector<string> AUPluginUI::automation_mode_strings;
49 static const gchar* _automation_mode_strings[] = {
58 dump_view_tree (NSView* view, int depth, int maxdepth)
60 NSArray* subviews = [view subviews];
61 unsigned long cnt = [subviews count];
63 for (int d = 0; d < depth; d++) {
66 NSRect frame = [view frame];
67 cerr << " view @ " << frame.origin.x << ", " << frame.origin.y
68 << ' ' << frame.size.width << " x " << frame.size.height
71 if (depth >= maxdepth) {
74 for (unsigned long i = 0; i < cnt; ++i) {
75 NSView* subview = [subviews objectAtIndex:i];
76 dump_view_tree (subview, depth+1, maxdepth);
80 @implementation NotificationObject
82 - (NotificationObject*) initWithPluginUI: (AUPluginUI*) apluginui andCocoaParent: (NSWindow*) cp andTopLevelParent: (NSWindow*) tlp
84 self = [ super init ];
87 plugin_ui = apluginui;
88 top_level_parent = tlp;
93 [[NSNotificationCenter defaultCenter]
95 selector:@selector(cocoaParentActivationHandler:)
96 name:NSWindowDidBecomeMainNotification
99 [[NSNotificationCenter defaultCenter]
101 selector:@selector(cocoaParentBecameKeyHandler:)
102 name:NSWindowDidBecomeKeyNotification
110 - (void)cocoaParentActivationHandler:(NSNotification *)notification
112 NSWindow* notification_window = (NSWindow *)[notification object];
114 if (top_level_parent == notification_window || cocoa_parent == notification_window) {
115 if ([notification_window isMainWindow]) {
116 plugin_ui->activate();
118 plugin_ui->deactivate();
123 - (void)cocoaParentBecameKeyHandler:(NSNotification *)notification
125 NSWindow* notification_window = (NSWindow *)[notification object];
127 if (top_level_parent == notification_window || cocoa_parent == notification_window) {
128 if ([notification_window isKeyWindow]) {
129 plugin_ui->activate();
131 plugin_ui->deactivate();
136 - (void)auViewResized:(NSNotification *)notification
138 (void) notification; // stop complaints about unusued argument
139 plugin_ui->cocoa_view_resized();
144 @implementation LiveResizeNotificationObject
146 - (LiveResizeNotificationObject*) initWithPluginUI: (AUPluginUI*) apluginui
148 self = [ super init ];
150 plugin_ui = apluginui;
156 - (void)windowWillStartLiveResizeHandler:(NSNotification*)notification
158 plugin_ui->start_live_resize ();
161 - (void)windowWillEndLiveResizeHandler:(NSNotification*)notification
163 plugin_ui->end_live_resize ();
167 AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
168 : PlugUIBase (insert)
169 , automation_mode_label (_("Automation"))
170 , preset_label (_("Presets"))
181 , in_live_resize (false)
182 , plugin_requested_resize (0)
188 if (automation_mode_strings.empty()) {
189 automation_mode_strings = I18N (_automation_mode_strings);
192 set_popdown_strings (automation_mode_selector, automation_mode_strings);
193 automation_mode_selector.set_active_text (automation_mode_strings.front());
195 if ((au = boost::dynamic_pointer_cast<AUPlugin> (insert->plugin())) == 0) {
196 error << _("unknown type of editor-supplying plugin (note: no AudioUnit support in this version of ardour)") << endmsg;
197 throw failed_constructor ();
200 /* stuff some stuff into the top of the window */
202 HBox* smaller_hbox = manage (new HBox);
204 smaller_hbox->set_spacing (6);
205 smaller_hbox->pack_start (preset_label, false, false, 4);
206 smaller_hbox->pack_start (_preset_modified, false, false);
207 smaller_hbox->pack_start (_preset_combo, false, false);
208 smaller_hbox->pack_start (add_button, false, false);
210 /* Ardour does not currently allow to overwrite existing presets
211 * see save_property_list() in audio_unit.cc
213 smaller_hbox->pack_start (save_button, false, false);
216 /* one day these might be useful with an AU plugin, but not yet */
217 smaller_hbox->pack_start (automation_mode_label, false, false);
218 smaller_hbox->pack_start (automation_mode_selector, false, false);
220 smaller_hbox->pack_start (reset_button, false, false);
221 smaller_hbox->pack_start (bypass_button, false, true);
223 VBox* v1_box = manage (new VBox);
224 VBox* v2_box = manage (new VBox);
226 v1_box->pack_start (*smaller_hbox, false, true);
227 v2_box->pack_start (focus_button, false, true);
229 top_box.set_homogeneous (false);
230 top_box.set_spacing (6);
231 top_box.set_border_width (6);
233 top_box.pack_end (*v2_box, false, false);
234 top_box.pack_end (*v1_box, false, false);
237 pack_start (top_box, false, false);
238 pack_start (low_box, true, true);
240 preset_label.show ();
241 _preset_combo.show ();
242 automation_mode_label.show ();
243 automation_mode_selector.show ();
244 bypass_button.show ();
252 _activating_from_app = false;
259 /* prefer cocoa, fall back to cocoa, but use carbon if its there */
261 if (test_cocoa_view_support()) {
262 create_cocoa_view ();
264 } else if (test_carbon_view_support()) {
265 create_carbon_view ();
268 create_cocoa_view ();
271 low_box.add_events (Gdk::VISIBILITY_NOTIFY_MASK | Gdk::EXPOSURE_MASK);
273 low_box.signal_realize().connect (mem_fun (this, &AUPluginUI::lower_box_realized));
274 low_box.signal_visibility_notify_event ().connect (mem_fun (this, &AUPluginUI::lower_box_visibility_notify));
276 low_box.signal_size_request ().connect (mem_fun (this, &AUPluginUI::lower_box_size_request));
277 low_box.signal_size_allocate ().connect (mem_fun (this, &AUPluginUI::lower_box_size_allocate));
278 low_box.signal_map ().connect (mem_fun (this, &AUPluginUI::lower_box_map));
279 low_box.signal_unmap ().connect (mem_fun (this, &AUPluginUI::lower_box_unmap));
280 low_box.signal_expose_event ().connect (mem_fun (this, &AUPluginUI::lower_box_expose));
284 AUPluginUI::~AUPluginUI ()
287 [[NSNotificationCenter defaultCenter] removeObserver:_notify];
290 if (_resize_notify) {
291 [[NSNotificationCenter defaultCenter] removeObserver:_resize_notify];
295 NSWindow* win = get_nswindow();
296 [win removeChildWindow:cocoa_parent];
301 /* not parented, just overlaid on top of our window */
302 DisposeWindow (carbon_window);
307 ArdourCloseComponent (editView);
311 /* remove whatever we packed into low_box so that GTK doesn't
315 [au_view removeFromSuperview];
320 AUPluginUI::test_carbon_view_support ()
325 carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType;
326 carbon_descriptor.componentSubType = 'gnrc';
327 carbon_descriptor.componentManufacturer = 'appl';
328 carbon_descriptor.componentFlags = 0;
329 carbon_descriptor.componentFlagsMask = 0;
333 // ask the AU for its first editor component
335 err = AudioUnitGetPropertyInfo(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, &propertySize, NULL);
337 int nEditors = propertySize / sizeof(ComponentDescription);
338 ComponentDescription *editors = new ComponentDescription[nEditors];
339 err = AudioUnitGetProperty(*au->get_au(), kAudioUnitProperty_GetUIComponentList, kAudioUnitScope_Global, 0, editors, &propertySize);
341 // just pick the first one for now
342 carbon_descriptor = editors[0];
355 AUPluginUI::test_cocoa_view_support ()
358 Boolean isWritable = 0;
359 OSStatus err = AudioUnitGetPropertyInfo(*au->get_au(),
360 kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
361 0, &dataSize, &isWritable);
363 return dataSize > 0 && err == noErr;
367 AUPluginUI::plugin_class_valid (Class pluginClass)
369 if([pluginClass conformsToProtocol: @protocol(AUCocoaUIBase)]) {
370 if([pluginClass instancesRespondToSelector: @selector(interfaceVersion)] &&
371 [pluginClass instancesRespondToSelector: @selector(uiViewForAudioUnit:withSize:)]) {
379 AUPluginUI::create_cocoa_view ()
381 bool wasAbleToLoadCustomView = false;
382 AudioUnitCocoaViewInfo* cocoaViewInfo = NULL;
383 UInt32 numberOfClasses = 0;
386 NSString* factoryClassName = 0;
387 NSURL* CocoaViewBundlePath = NULL;
389 OSStatus result = AudioUnitGetPropertyInfo (*au->get_au(),
390 kAudioUnitProperty_CocoaUI,
391 kAudioUnitScope_Global,
396 numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
398 // Does view have custom Cocoa UI?
400 if ((result == noErr) && (numberOfClasses > 0) ) {
402 DEBUG_TRACE(DEBUG::AudioUnits,
403 string_compose ( "based on %1, there are %2 cocoa UI classes\n", dataSize, numberOfClasses));
405 cocoaViewInfo = (AudioUnitCocoaViewInfo *)malloc(dataSize);
407 if(AudioUnitGetProperty(*au->get_au(),
408 kAudioUnitProperty_CocoaUI,
409 kAudioUnitScope_Global,
412 &dataSize) == noErr) {
414 CocoaViewBundlePath = (NSURL *)cocoaViewInfo->mCocoaAUViewBundleLocation;
416 // we only take the first view in this example.
417 factoryClassName = (NSString *)cocoaViewInfo->mCocoaAUViewClass[0];
419 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("the factory name is %1 bundle is %2\n",
420 [factoryClassName UTF8String], CocoaViewBundlePath));
424 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("No cocoaUI property cocoaViewInfo = %1\n", cocoaViewInfo));
426 if (cocoaViewInfo != NULL) {
427 free (cocoaViewInfo);
428 cocoaViewInfo = NULL;
433 // [A] Show custom UI if view has it
435 if (CocoaViewBundlePath && factoryClassName) {
436 NSBundle *viewBundle = [NSBundle bundleWithPath:[CocoaViewBundlePath path]];
438 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("tried to create bundle, result = %1\n", viewBundle));
440 if (viewBundle == NULL) {
441 error << _("AUPluginUI: error loading AU view's bundle") << endmsg;
444 Class factoryClass = [viewBundle classNamed:factoryClassName];
445 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("tried to create factory class, result = %1\n", factoryClass));
447 error << _("AUPluginUI: error getting AU view's factory class from bundle") << endmsg;
451 // make sure 'factoryClass' implements the AUCocoaUIBase protocol
452 if (!plugin_class_valid (factoryClass)) {
453 error << _("AUPluginUI: U view's factory class does not properly implement the AUCocoaUIBase protocol") << endmsg;
457 id factory = [[[factoryClass alloc] init] autorelease];
458 if (factory == NULL) {
459 error << _("AUPluginUI: Could not create an instance of the AU view factory") << endmsg;
463 DEBUG_TRACE (DEBUG::AudioUnits, "got a factory instance\n");
466 au_view = [factory uiViewForAudioUnit:*au->get_au() withSize:NSZeroSize];
468 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("view created @ %1\n", au_view));
471 [CocoaViewBundlePath release];
474 for (i = 0; i < numberOfClasses; i++)
475 CFRelease(cocoaViewInfo->mCocoaAUViewClass[i]);
477 free (cocoaViewInfo);
479 wasAbleToLoadCustomView = true;
483 if (!wasAbleToLoadCustomView) {
484 // load generic Cocoa view
485 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("Loading generic view using %1 -> %2\n", au,
487 au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()];
488 DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("view created @ %1\n", au_view));
489 [(AUGenericView *)au_view setShowsExpertParameters:1];
492 // Get the initial size of the new AU View's frame
493 NSRect frame = [au_view frame];
494 min_width = req_width = frame.size.width;
495 min_height = req_height = frame.size.height;
497 resizable = [au_view autoresizingMask];
498 std::cerr << plugin->name() << " initial frame = " << [NSStringFromRect (frame) UTF8String] << " resizable ? " << resizable << std::endl;
500 low_box.queue_resize ();
506 AUPluginUI::update_view_size ()
508 last_au_frame = [au_view frame];
512 AUPluginUI::cocoa_view_resized ()
514 /* we can get here for two reasons:
516 1) the plugin window was resized by the user, a new size was
517 allocated to the window, ::update_view_size() was called, and we
518 explicitly/manually resized the AU NSView.
520 2) the plugin decided to resize itself (probably in response to user
521 action, but not in response to an actual window resize)
523 We only want to proceed with a window resizing in the second case.
526 if (in_live_resize) {
527 /* ::update_view_size() will be called at the right times and
528 * will update the view size. We don't need to anything while a
529 * live resize in underway.
534 if (plugin_requested_resize) {
535 /* we tried to change the plugin frame from inside this method
536 * (to adjust the origin), and the plugin changed its size
537 * again. Ignore this second call.
539 std::cerr << plugin->name() << " re-entrant call to cocoa_view_resized, ignored\n";
543 plugin_requested_resize = 1;
545 ProcessorWindowProxy* wp = insert->window_proxy();
547 /* Once a plugin has requested a resize of its own window, do
548 * NOT save the window. The user may save state with the plugin
549 * editor expanded to show "extra detail" - the plugin will not
550 * refill this space when the editor is first
551 * instantiated. Leaving the window in the "too big" state
552 * cannot be recovered from.
554 * The window will be sized to fit the plugin's own request. Done.
556 wp->set_state_mask (WindowProxy::Position);
559 NSRect new_frame = [au_view frame];
561 std::cerr << "Plugin " << plugin->name() << " requested update (prs now = " << plugin_requested_resize << ")\n";
562 std::cerr << "\tAU NSView frame : " << [ NSStringFromRect (new_frame) UTF8String] << std::endl;
563 std::cerr << "\tlast au frame : " << [ NSStringFromRect (last_au_frame) UTF8String] << std::endl;
565 /* from here on, we know that we've been called because the plugin
566 * decided to change the NSView frame itself.
569 /* step one: compute the change in the frame size.
572 float dy = new_frame.size.height - last_au_frame.size.height;
573 float dx = new_frame.size.width - last_au_frame.size.width;
575 NSWindow* window = get_nswindow ();
576 NSRect windowFrame= [window frame];
578 /* we want the top edge of the window to remain in the same place,
579 but the Cocoa/Quartz origin is at the lower left. So, when we make
580 the window larger, we will move it down, which means shifting the
581 origin toward (x,0). This will leave the top edge in the same place.
584 windowFrame.origin.y -= dy;
585 windowFrame.origin.x -= dx;
586 windowFrame.size.height += dy;
587 windowFrame.size.width += dx;
589 std::cerr << "\tChange size by " << dx << " x " << dy << std::endl;
591 NSUInteger old_auto_resize = [au_view autoresizingMask];
593 /* Stop the AU NSView from resizing itself *again* in response to
594 us changing the window size.
598 [au_view setAutoresizingMask:NSViewNotSizable];
600 /* this resizes the window. it will eventually trigger a new
601 * size_allocate event/callback, and we'll end up in
602 * ::update_view_size(). We want to stop that from doing anything,
603 * because we've already resized the window to fit the new new view,
604 * so there's no need to actually update the view size again.
607 [window setFrame:windowFrame display:1];
609 /* Some stupid AU Views change the origin of the original AU View when
610 they are resized (I'm looking at you AUSampler). If the origin has
611 been moved, move it back.
614 if (last_au_frame.origin.x != new_frame.origin.x ||
615 last_au_frame.origin.y != new_frame.origin.y) {
616 new_frame.origin = last_au_frame.origin;
617 std::cerr << "Move AU NSView origin back to "
618 << new_frame.origin.x << ", " << new_frame.origin.y
620 [au_view setFrame:new_frame];
621 /* also be sure to redraw the topbox because this can
624 top_box.queue_draw ();
627 [au_view setAutoresizingMask:old_auto_resize];
629 /* keep a copy of the size of the AU NSView. We didn't set - the plugin did */
630 last_au_frame = new_frame;
631 min_width = req_width = new_frame.size.width;
632 min_height = req_height = new_frame.size.height;
634 plugin_requested_resize = 0;
638 AUPluginUI::create_carbon_view ()
642 ControlRef root_control;
644 Component editComponent = FindNextComponent(NULL, &carbon_descriptor);
646 OpenAComponent(editComponent, &editView);
648 error << _("AU Carbon view: cannot open AU Component") << endmsg;
652 Rect r = { 100, 100, 100, 100 };
653 WindowAttributes attr = WindowAttributes (kWindowStandardHandlerAttribute |
654 kWindowCompositingAttribute|
655 kWindowNoShadowAttribute|
656 kWindowNoTitleBarAttribute);
658 if ((err = CreateNewWindow(kUtilityWindowClass, attr, &r, &carbon_window)) != noErr) {
659 error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
660 ArdourCloseComponent (editView);
664 if ((err = GetRootControl(carbon_window, &root_control)) != noErr) {
665 error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg;
666 DisposeWindow (carbon_window);
667 ArdourCloseComponent (editView);
672 Float32Point location = { 0.0, 0.0 };
673 Float32Point size = { 0.0, 0.0 } ;
675 if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) {
676 error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg;
677 DisposeWindow (carbon_window);
678 ArdourCloseComponent (editView);
685 GetControlBounds(viewPane, &bounds);
686 size.x = bounds.right-bounds.left;
687 size.y = bounds.bottom-bounds.top;
689 req_width = (int) (size.x + 0.5);
690 req_height = (int) (size.y + 0.5);
692 SizeWindow (carbon_window, req_width, req_height, true);
693 low_box.set_size_request (req_width, req_height);
697 error << _("AU Carbon GUI is not supported.") << endmsg;
703 AUPluginUI::get_nswindow ()
705 Gtk::Container* toplevel = get_toplevel();
707 if (!toplevel || !toplevel->is_toplevel()) {
708 error << _("AUPluginUI: no top level window!") << endmsg;
712 NSWindow* true_parent = gdk_quartz_window_get_nswindow (toplevel->get_window()->gobj());
715 error << _("AUPluginUI: no top level window!") << endmsg;
723 AUPluginUI::activate ()
726 ActivateWindow (carbon_window, TRUE);
731 AUPluginUI::deactivate ()
734 ActivateWindow (carbon_window, FALSE);
739 AUPluginUI::parent_carbon_window ()
742 NSWindow* win = get_nswindow ();
743 Rect windowStructureBoundsRect;
749 /* figure out where the cocoa parent window is in carbon-coordinate space, which
750 differs from both cocoa-coordinate space and GTK-coordinate space
753 GetWindowBounds((WindowRef) [win windowRef], kWindowStructureRgn, &windowStructureBoundsRect);
755 /* compute how tall the title bar is, because we have to offset the position of the carbon window
759 NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]];
760 NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]];
762 int titlebar_height = wm_frame.size.height - content_frame.size.height;
764 int packing_extra = 6; // this is the total vertical packing in our top level window
766 /* move into position, based on parent window position */
767 MoveWindow (carbon_window,
768 windowStructureBoundsRect.left,
769 windowStructureBoundsRect.top + titlebar_height + top_box.get_height() + packing_extra,
771 ShowWindow (carbon_window);
773 // create the cocoa window for the carbon one and make it visible
774 cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
776 SetWindowActivationScope (carbon_window, kWindowActivationScopeNone);
778 _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ];
780 [win addChildWindow:cocoa_parent ordered:NSWindowAbove];
781 [win setAutodisplay:1]; // turn of GTK stuff for this window
790 AUPluginUI::parent_cocoa_window ()
792 NSWindow* win = get_nswindow ();
798 //[win setAutodisplay:1]; // turn off GTK stuff for this window
800 NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj());
801 [view addSubview:au_view];
803 /* this moves the AU NSView down and over to provide a left-hand margin
804 * and to clear the Ardour "task bar" (with plugin preset mgmt buttons,
805 * keyboard focus control, bypass etc).
809 gtk_widget_translate_coordinates(
810 GTK_WIDGET(low_box.gobj()),
811 GTK_WIDGET(low_box.get_parent()->gobj()),
813 [au_view setFrame:NSMakeRect(xx, yy, req_width, req_height)];
815 last_au_frame = [au_view frame];
816 // watch for size changes of the view
817 _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:NULL andTopLevelParent:win ];
819 [[NSNotificationCenter defaultCenter] addObserver:_notify
820 selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification
823 // catch notifications that live resizing is about to start
825 _resize_notify = [ [ LiveResizeNotificationObject alloc] initWithPluginUI:this ];
827 [[NSNotificationCenter defaultCenter] addObserver:_resize_notify
828 selector:@selector(windowWillStartLiveResizeHandler:) name:NSWindowWillStartLiveResizeNotification
831 [[NSNotificationCenter defaultCenter] addObserver:_resize_notify
832 selector:@selector(windowWillEndLiveResizeHandler:) name:NSWindowDidEndLiveResizeNotification
839 AUPluginUI::grab_focus()
842 [au_view becomeFirstResponder];
846 AUPluginUI::forward_key_event (GdkEventKey* ev)
848 NSEvent* nsevent = gdk_quartz_event_get_nsevent ((GdkEvent*)ev);
850 if (au_view && nsevent) {
852 /* filter on nsevent type here because GDK massages FlagsChanged
853 messages into GDK_KEY_{PRESS,RELEASE} but Cocoa won't
854 handle a FlagsChanged message as a keyDown or keyUp
857 if ([nsevent type] == NSKeyDown) {
858 [[[au_view window] firstResponder] keyDown:nsevent];
859 } else if ([nsevent type] == NSKeyUp) {
860 [[[au_view window] firstResponder] keyUp:nsevent];
861 } else if ([nsevent type] == NSFlagsChanged) {
862 [[[au_view window] firstResponder] flagsChanged:nsevent];
868 AUPluginUI::on_realize ()
872 /* our windows should not have that resize indicator */
874 NSWindow* win = get_nswindow ();
876 [win setShowsResizeIndicator:0];
881 AUPluginUI::lower_box_realized ()
884 parent_cocoa_window ();
885 } else if (carbon_window) {
886 parent_carbon_window ();
891 AUPluginUI::lower_box_visibility_notify (GdkEventVisibility* ev)
894 if (carbon_window && ev->state != GDK_VISIBILITY_UNOBSCURED) {
895 ShowWindow (carbon_window);
896 ActivateWindow (carbon_window, TRUE);
904 AUPluginUI::lower_box_map ()
907 [au_view setHidden:0];
912 AUPluginUI::lower_box_unmap ()
915 [au_view setHidden:1];
919 AUPluginUI::lower_box_size_request (GtkRequisition* requisition)
921 requisition->width = req_width;
922 requisition->height = req_height;
926 AUPluginUI::lower_box_size_allocate (Gtk::Allocation& allocation)
928 alo_width = allocation.get_width ();
929 alo_height = allocation.get_height ();
930 std::cerr << "lower box size reallocated to " << alo_width << " x " << alo_height << std::endl;
932 std::cerr << "low box draw (0, 0, " << alo_width << " x " << alo_height << ")\n";
933 low_box.queue_draw_area (0, 0, alo_width, alo_height);
937 AUPluginUI::lower_box_expose (GdkEventExpose* event)
939 std::cerr << "lower box expose: " << event->area.x << ", " << event->area.y
941 << event->area.width << " x " << event->area.height
943 << get_allocation().get_width() << " x " << get_allocation().get_height()
946 /* hack to keep ardour responsive
947 * some UIs (e.g Addictive Drums) completely hog the CPU
955 AUPluginUI::on_window_hide ()
959 HideWindow (carbon_window);
960 ActivateWindow (carbon_window, FALSE);
966 NSArray* wins = [NSApp windows];
967 for (uint32_t i = 0; i < [wins count]; i++) {
968 id win = [wins objectAtIndex:i];
974 AUPluginUI::on_window_show (const string& /*title*/)
976 /* this is idempotent so just call it every time we show the window */
978 gtk_widget_realize (GTK_WIDGET(low_box.gobj()));
984 ShowWindow (carbon_window);
985 ActivateWindow (carbon_window, TRUE);
993 AUPluginUI::start_updating (GdkEventAny*)
999 AUPluginUI::stop_updating (GdkEventAny*)
1005 create_au_gui (boost::shared_ptr<PluginInsert> plugin_insert, VBox** box)
1007 AUPluginUI* aup = new AUPluginUI (plugin_insert);
1013 AUPluginUI::start_live_resize ()
1015 std::cerr << "\n\n\n++++ Entering Live Resize\n";
1016 in_live_resize = true;
1020 AUPluginUI::end_live_resize ()
1022 std::cerr << "\n\n\n ----Leaving Live Resize\n";
1023 in_live_resize = false;