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 /* Some stupid AU Views change the origin of the original AU View when
601 they are resized (I'm looking at you AUSampler). If the origin has
602 been moved, move it back.
605 if (last_au_frame.origin.x != new_frame.origin.x ||
606 last_au_frame.origin.y != new_frame.origin.y) {
607 new_frame.origin = last_au_frame.origin;
608 std::cerr << "Move AU NSView origin back to "
609 << new_frame.origin.x << ", " << new_frame.origin.y
611 [au_view setFrame:new_frame];
612 /* also be sure to redraw the topbox because this can
615 top_box.queue_draw ();
617 std::cerr << "No need to move origin, last au origin " << [NSStringFromPoint(last_au_frame.origin) UTF8String]
618 << " == new au origin " << [NSStringFromPoint(new_frame.origin) UTF8String]
622 /* this resizes the window. it will eventually trigger a new
623 * size_allocate event/callback, and we'll end up in
624 * ::update_view_size(). We want to stop that from doing anything,
625 * because we've already resized the window to fit the new new view,
626 * so there's no need to actually update the view size again.
629 [window setFrame:windowFrame display:1];
631 [au_view setAutoresizingMask:old_auto_resize];
633 /* keep a copy of the size of the AU NSView. We didn't set - the plugin did */
634 last_au_frame = new_frame;
635 min_width = req_width = new_frame.size.width;
636 min_height = req_height = new_frame.size.height;
638 plugin_requested_resize = 0;
642 AUPluginUI::create_carbon_view ()
646 ControlRef root_control;
648 Component editComponent = FindNextComponent(NULL, &carbon_descriptor);
650 OpenAComponent(editComponent, &editView);
652 error << _("AU Carbon view: cannot open AU Component") << endmsg;
656 Rect r = { 100, 100, 100, 100 };
657 WindowAttributes attr = WindowAttributes (kWindowStandardHandlerAttribute |
658 kWindowCompositingAttribute|
659 kWindowNoShadowAttribute|
660 kWindowNoTitleBarAttribute);
662 if ((err = CreateNewWindow(kUtilityWindowClass, attr, &r, &carbon_window)) != noErr) {
663 error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
664 ArdourCloseComponent (editView);
668 if ((err = GetRootControl(carbon_window, &root_control)) != noErr) {
669 error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg;
670 DisposeWindow (carbon_window);
671 ArdourCloseComponent (editView);
676 Float32Point location = { 0.0, 0.0 };
677 Float32Point size = { 0.0, 0.0 } ;
679 if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) {
680 error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg;
681 DisposeWindow (carbon_window);
682 ArdourCloseComponent (editView);
689 GetControlBounds(viewPane, &bounds);
690 size.x = bounds.right-bounds.left;
691 size.y = bounds.bottom-bounds.top;
693 req_width = (int) (size.x + 0.5);
694 req_height = (int) (size.y + 0.5);
696 SizeWindow (carbon_window, req_width, req_height, true);
697 low_box.set_size_request (req_width, req_height);
701 error << _("AU Carbon GUI is not supported.") << endmsg;
707 AUPluginUI::get_nswindow ()
709 Gtk::Container* toplevel = get_toplevel();
711 if (!toplevel || !toplevel->is_toplevel()) {
712 error << _("AUPluginUI: no top level window!") << endmsg;
716 NSWindow* true_parent = gdk_quartz_window_get_nswindow (toplevel->get_window()->gobj());
719 error << _("AUPluginUI: no top level window!") << endmsg;
727 AUPluginUI::activate ()
730 ActivateWindow (carbon_window, TRUE);
735 AUPluginUI::deactivate ()
738 ActivateWindow (carbon_window, FALSE);
743 AUPluginUI::parent_carbon_window ()
746 NSWindow* win = get_nswindow ();
747 Rect windowStructureBoundsRect;
753 /* figure out where the cocoa parent window is in carbon-coordinate space, which
754 differs from both cocoa-coordinate space and GTK-coordinate space
757 GetWindowBounds((WindowRef) [win windowRef], kWindowStructureRgn, &windowStructureBoundsRect);
759 /* compute how tall the title bar is, because we have to offset the position of the carbon window
763 NSRect content_frame = [NSWindow contentRectForFrameRect:[win frame] styleMask:[win styleMask]];
764 NSRect wm_frame = [NSWindow frameRectForContentRect:content_frame styleMask:[win styleMask]];
766 int titlebar_height = wm_frame.size.height - content_frame.size.height;
768 int packing_extra = 6; // this is the total vertical packing in our top level window
770 /* move into position, based on parent window position */
771 MoveWindow (carbon_window,
772 windowStructureBoundsRect.left,
773 windowStructureBoundsRect.top + titlebar_height + top_box.get_height() + packing_extra,
775 ShowWindow (carbon_window);
777 // create the cocoa window for the carbon one and make it visible
778 cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
780 SetWindowActivationScope (carbon_window, kWindowActivationScopeNone);
782 _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ];
784 [win addChildWindow:cocoa_parent ordered:NSWindowAbove];
785 [win setAutodisplay:1]; // turn of GTK stuff for this window
794 AUPluginUI::parent_cocoa_window ()
796 NSWindow* win = get_nswindow ();
802 //[win setAutodisplay:1]; // turn off GTK stuff for this window
804 NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj());
805 [view addSubview:au_view];
807 /* this moves the AU NSView down and over to provide a left-hand margin
808 * and to clear the Ardour "task bar" (with plugin preset mgmt buttons,
809 * keyboard focus control, bypass etc).
813 gtk_widget_translate_coordinates(
814 GTK_WIDGET(low_box.gobj()),
815 GTK_WIDGET(low_box.get_parent()->gobj()),
817 [au_view setFrame:NSMakeRect(xx, yy, req_width, req_height)];
819 last_au_frame = [au_view frame];
820 // watch for size changes of the view
821 _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:NULL andTopLevelParent:win ];
823 [[NSNotificationCenter defaultCenter] addObserver:_notify
824 selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification
827 // catch notifications that live resizing is about to start
829 _resize_notify = [ [ LiveResizeNotificationObject alloc] initWithPluginUI:this ];
831 [[NSNotificationCenter defaultCenter] addObserver:_resize_notify
832 selector:@selector(windowWillStartLiveResizeHandler:) name:NSWindowWillStartLiveResizeNotification
835 [[NSNotificationCenter defaultCenter] addObserver:_resize_notify
836 selector:@selector(windowWillEndLiveResizeHandler:) name:NSWindowDidEndLiveResizeNotification
843 AUPluginUI::grab_focus()
846 [au_view becomeFirstResponder];
850 AUPluginUI::forward_key_event (GdkEventKey* ev)
852 NSEvent* nsevent = gdk_quartz_event_get_nsevent ((GdkEvent*)ev);
854 if (au_view && nsevent) {
856 /* filter on nsevent type here because GDK massages FlagsChanged
857 messages into GDK_KEY_{PRESS,RELEASE} but Cocoa won't
858 handle a FlagsChanged message as a keyDown or keyUp
861 if ([nsevent type] == NSKeyDown) {
862 [[[au_view window] firstResponder] keyDown:nsevent];
863 } else if ([nsevent type] == NSKeyUp) {
864 [[[au_view window] firstResponder] keyUp:nsevent];
865 } else if ([nsevent type] == NSFlagsChanged) {
866 [[[au_view window] firstResponder] flagsChanged:nsevent];
872 AUPluginUI::on_realize ()
876 /* our windows should not have that resize indicator */
878 NSWindow* win = get_nswindow ();
880 [win setShowsResizeIndicator:0];
885 AUPluginUI::lower_box_realized ()
888 parent_cocoa_window ();
889 } else if (carbon_window) {
890 parent_carbon_window ();
895 AUPluginUI::lower_box_visibility_notify (GdkEventVisibility* ev)
898 if (carbon_window && ev->state != GDK_VISIBILITY_UNOBSCURED) {
899 ShowWindow (carbon_window);
900 ActivateWindow (carbon_window, TRUE);
908 AUPluginUI::lower_box_map ()
911 [au_view setHidden:0];
916 AUPluginUI::lower_box_unmap ()
919 [au_view setHidden:1];
923 AUPluginUI::lower_box_size_request (GtkRequisition* requisition)
925 requisition->width = req_width;
926 requisition->height = req_height;
930 AUPluginUI::lower_box_size_allocate (Gtk::Allocation& allocation)
932 alo_width = allocation.get_width ();
933 alo_height = allocation.get_height ();
934 std::cerr << "lower box size reallocated to " << alo_width << " x " << alo_height << std::endl;
936 std::cerr << "low box draw (0, 0, " << alo_width << " x " << alo_height << ")\n";
937 low_box.queue_draw_area (0, 0, alo_width, alo_height);
941 AUPluginUI::lower_box_expose (GdkEventExpose* event)
943 std::cerr << "lower box expose: " << event->area.x << ", " << event->area.y
945 << event->area.width << " x " << event->area.height
947 << get_allocation().get_width() << " x " << get_allocation().get_height()
950 /* hack to keep ardour responsive
951 * some UIs (e.g Addictive Drums) completely hog the CPU
959 AUPluginUI::on_window_hide ()
963 HideWindow (carbon_window);
964 ActivateWindow (carbon_window, FALSE);
970 NSArray* wins = [NSApp windows];
971 for (uint32_t i = 0; i < [wins count]; i++) {
972 id win = [wins objectAtIndex:i];
978 AUPluginUI::on_window_show (const string& /*title*/)
980 /* this is idempotent so just call it every time we show the window */
982 gtk_widget_realize (GTK_WIDGET(low_box.gobj()));
988 ShowWindow (carbon_window);
989 ActivateWindow (carbon_window, TRUE);
997 AUPluginUI::start_updating (GdkEventAny*)
1003 AUPluginUI::stop_updating (GdkEventAny*)
1009 create_au_gui (boost::shared_ptr<PluginInsert> plugin_insert, VBox** box)
1011 AUPluginUI* aup = new AUPluginUI (plugin_insert);
1017 AUPluginUI::start_live_resize ()
1019 std::cerr << "\n\n\n++++ Entering Live Resize\n";
1020 in_live_resize = true;
1024 AUPluginUI::end_live_resize ()
1026 std::cerr << "\n\n\n ----Leaving Live Resize\n";
1027 in_live_resize = false;