X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fau_pluginui.mm;h=3682788a74619bd4ea2e5540f6bf53007b2cc86c;hb=2d47183dc962bddd2084676b59e9f2c4a0abe33b;hp=5ebd464af0ed227ed54f63f69426373be655d76b;hpb=a025337960847c6d85cc05ef14bfe9b7c3f92c5b;p=ardour.git diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index 5ebd464af0..3682788a74 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -1,8 +1,9 @@ -#include - #undef Marker #define Marker FuckYouAppleAndYourLackOfNameSpaces +#include +#include + #include "pbd/convert.h" #include "pbd/error.h" @@ -12,9 +13,6 @@ #undef check // stupid gtk, stupid apple -#include -#include - #include #include "au_pluginui.h" @@ -36,7 +34,6 @@ using namespace ARDOUR; using namespace Gtk; using namespace Gtkmm2ext; -using namespace sigc; using namespace std; using namespace PBD; @@ -50,6 +47,26 @@ static const gchar* _automation_mode_strings[] = { 0 }; +static void +dump_view_tree (NSView* view, int depth) +{ + NSArray* subviews = [view subviews]; + unsigned long cnt = [subviews count]; + + for (int d = 0; d < depth; d++) { + cerr << '\t'; + } + NSRect frame = [view frame]; + cerr << " view @ " << frame.origin.x << ", " << frame.origin.y + << ' ' << frame.size.width << " x " << frame.size.height + << endl; + + for (unsigned long i = 0; i < cnt; ++i) { + NSView* subview = [subviews objectAtIndex:i]; + dump_view_tree (subview, depth+1); + } +} + @implementation NotificationObject - (NotificationObject*) initWithPluginUI: (AUPluginUI*) apluginui andCocoaParent: (NSWindow*) cp andTopLevelParent: (NSWindow*) tlp @@ -66,12 +83,12 @@ static const gchar* _automation_mode_strings[] = { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cocoaParentActivationHandler:) name:NSWindowDidBecomeMainNotification - object:nil]; + object:NULL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cocoaParentBecameKeyHandler:) name:NSWindowDidBecomeKeyNotification - object:nil]; + object:NULL]; } } @@ -104,7 +121,7 @@ static const gchar* _automation_mode_strings[] = { } } -- (void)auViewResized:(NSNotification *)notification; +- (void)auViewResized:(NSNotification *)notification { (void) notification; // stop complaints about unusued argument plugin_ui->cocoa_view_resized(); @@ -136,13 +153,21 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) smaller_hbox->set_spacing (6); smaller_hbox->pack_start (preset_label, false, false, 4); + smaller_hbox->pack_start (_preset_modified, false, false); smaller_hbox->pack_start (_preset_combo, false, false); + smaller_hbox->pack_start (add_button, false, false); +#if 0 + /* Ardour does not currently allow to overwrite existing presets + * see save_property_list() in audio_unit.cc + */ smaller_hbox->pack_start (save_button, false, false); +#endif #if 0 /* one day these might be useful with an AU plugin, but not yet */ smaller_hbox->pack_start (automation_mode_label, false, false); smaller_hbox->pack_start (automation_mode_selector, false, false); #endif + smaller_hbox->pack_start (reset_button, false, false); smaller_hbox->pack_start (bypass_button, false, true); VBox* v1_box = manage (new VBox); @@ -170,13 +195,16 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) top_box.show (); low_box.show (); - _activating_from_app = false; cocoa_parent = 0; - _notify = 0; cocoa_window = 0; - carbon_window = 0; + +#ifdef WITH_CARBON + _activating_from_app = false; + _notify = 0; au_view = 0; editView = 0; + carbon_window = 0; +#endif /* prefer cocoa, fall back to cocoa, but use carbon if its there */ @@ -190,16 +218,21 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) create_cocoa_view (); } + low_box.add_events(Gdk::VISIBILITY_NOTIFY_MASK); + low_box.signal_realize().connect (mem_fun (this, &AUPluginUI::lower_box_realized)); + low_box.signal_visibility_notify_event ().connect (mem_fun (this, &AUPluginUI::lower_box_visibility_notify)); } AUPluginUI::~AUPluginUI () { + if (_notify) { + [[NSNotificationCenter defaultCenter] removeObserver:_notify]; + } + if (cocoa_parent) { NSWindow* win = get_nswindow(); - [[NSNotificationCenter defaultCenter] removeObserver:_notify]; [win removeChildWindow:cocoa_parent]; - } #ifdef WITH_CARBON @@ -225,6 +258,7 @@ AUPluginUI::~AUPluginUI () bool AUPluginUI::test_carbon_view_support () { +#ifdef WITH_CARBON bool ret = false; carbon_descriptor.componentType = kAudioUnitCarbonViewComponentType; @@ -251,6 +285,9 @@ AUPluginUI::test_carbon_view_support () } return ret; +#else + return false; +#endif } bool @@ -280,7 +317,7 @@ AUPluginUI::plugin_class_valid (Class pluginClass) int AUPluginUI::create_cocoa_view () { - BOOL wasAbleToLoadCustomView = NO; + bool wasAbleToLoadCustomView = false; AudioUnitCocoaViewInfo* cocoaViewInfo = NULL; UInt32 numberOfClasses = 0; UInt32 dataSize; @@ -339,7 +376,7 @@ AUPluginUI::create_cocoa_view () DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("tried to create bundle, result = %1\n", viewBundle)); - if (viewBundle == nil) { + if (viewBundle == NULL) { error << _("AUPluginUI: error loading AU view's bundle") << endmsg; return -1; } else { @@ -357,7 +394,7 @@ AUPluginUI::create_cocoa_view () } // make a factory id factory = [[[factoryClass alloc] init] autorelease]; - if (factory == nil) { + if (factory == NULL) { error << _("AUPluginUI: Could not create an instance of the AU view factory") << endmsg; return -1; } @@ -378,7 +415,7 @@ AUPluginUI::create_cocoa_view () free (cocoaViewInfo); } - wasAbleToLoadCustomView = YES; + wasAbleToLoadCustomView = true; } } @@ -388,30 +425,28 @@ AUPluginUI::create_cocoa_view () au->get_au())); au_view = [[AUGenericView alloc] initWithAudioUnit:*au->get_au()]; DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("view created @ %1\n", au_view)); - [(AUGenericView *)au_view setShowsExpertParameters:YES]; + [(AUGenericView *)au_view setShowsExpertParameters:1]; } // Get the initial size of the new AU View's frame NSRect rect = [au_view frame]; + prefheight = rect.size.height; + prefwidth = rect.size.width; low_box.set_size_request (rect.size.width, rect.size.height); - + return 0; } void AUPluginUI::cocoa_view_resized () { - GtkRequisition topsize = top_box.size_request (); NSWindow* window = get_nswindow (); - NSSize oldContentSize= [window contentRectForFrameRect:[window frame]].size; - NSSize newContentSize= [au_view frame].size; NSRect windowFrame= [window frame]; - - oldContentSize.height -= topsize.height; + NSRect new_frame = [au_view frame]; - float dy = oldContentSize.height - newContentSize.height; - float dx = oldContentSize.width - newContentSize.width; + float dy = last_au_frame.size.height - new_frame.size.height; + float dx = last_au_frame.size.width - new_frame.size.width; windowFrame.origin.y += dy; windowFrame.origin.x += dx; @@ -425,12 +460,30 @@ AUPluginUI::cocoa_view_resized () NSUInteger old_auto_resize = [au_view autoresizingMask]; [au_view setAutoresizingMask:NSViewNotSizable]; - [window setFrame:windowFrame display:YES]; + [window setFrame:windowFrame display:1]; + + /* Some stupid AU Views change the origin of the original AU View + when they are resized (I'm looking at you AUSampler). If the origin + has been moved, move it back. + */ + + if (last_au_frame.origin.x != new_frame.origin.x || + last_au_frame.origin.y != new_frame.origin.y) { + new_frame.origin = last_au_frame.origin; + [au_view setFrame:new_frame]; + /* also be sure to redraw the topbox because this can + also go wrong. + */ + top_box.queue_draw (); + } + [au_view setAutoresizingMask:old_auto_resize]; [[NSNotificationCenter defaultCenter] addObserver:_notify selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification object:au_view]; + + last_au_frame = new_frame; } int @@ -454,7 +507,7 @@ AUPluginUI::create_carbon_view () kWindowNoShadowAttribute| kWindowNoTitleBarAttribute); - if ((err = CreateNewWindow(kDocumentWindowClass, attr, &r, &carbon_window)) != noErr) { + if ((err = CreateNewWindow(kUtilityWindowClass, attr, &r, &carbon_window)) != noErr) { error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg; CloseComponent (editView); return -1; @@ -524,7 +577,6 @@ AUPluginUI::activate () #ifdef WITH_CARBON ActivateWindow (carbon_window, TRUE); #endif - // [cocoa_parent makeKeyAndOrderFront:nil]; } void @@ -540,7 +592,7 @@ AUPluginUI::parent_carbon_window () { #ifdef WITH_CARBON NSWindow* win = get_nswindow (); - int x, y; + Rect windowStructureBoundsRect; if (!win) { return -1; @@ -553,7 +605,11 @@ AUPluginUI::parent_carbon_window () return -1; } - toplevel->get_window()->get_root_origin (x, y); + /* figure out where the cocoa parent window is in carbon-coordinate space, which + differs from both cocoa-coordinate space and GTK-coordinate space + */ + + GetWindowBounds((WindowRef) [win windowRef], kWindowStructureRgn, &windowStructureBoundsRect); /* compute how tall the title bar is, because we have to offset the position of the carbon window by that much. @@ -566,7 +622,11 @@ AUPluginUI::parent_carbon_window () int packing_extra = 6; // this is the total vertical packing in our top level window - MoveWindow (carbon_window, x, y + titlebar_height + top_box.get_height() + packing_extra, false); + /* move into position, based on parent window position */ + MoveWindow (carbon_window, + windowStructureBoundsRect.left, + windowStructureBoundsRect.top + titlebar_height + top_box.get_height() + packing_extra, + false); ShowWindow (carbon_window); // create the cocoa window for the carbon one and make it visible @@ -577,6 +637,7 @@ AUPluginUI::parent_carbon_window () _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ]; [win addChildWindow:cocoa_parent ordered:NSWindowAbove]; + [win setAutodisplay:1]; // turn of GTK stuff for this window return 0; #else @@ -593,7 +654,7 @@ AUPluginUI::parent_cocoa_window () return -1; } - [win setAutodisplay:YES]; // turn of GTK stuff for this window + [win setAutodisplay:1]; // turn of GTK stuff for this window Gtk::Container* toplevel = get_toplevel(); @@ -607,14 +668,19 @@ AUPluginUI::parent_cocoa_window () /* move the au_view down so that it doesn't overlap the top_box contents */ - NSPoint origin = { 0, a.height }; + const int spacing = 6; // main vbox spacing + const int pad = 4; // box pad + + NSPoint origin = { spacing + pad, static_cast (a.height) + (2 * spacing) + pad }; [au_view setFrameOrigin:origin]; - [view addSubview:au_view positioned:NSWindowBelow relativeTo:nil]; + [view addSubview:au_view positioned:NSWindowBelow relativeTo:NULL]; + + last_au_frame = [au_view frame]; // watch for size changes of the view - _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:nil andTopLevelParent:win ]; + _notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:NULL andTopLevelParent:win ]; [[NSNotificationCenter defaultCenter] addObserver:_notify selector:@selector(auViewResized:) name:NSViewFrameDidChangeNotification @@ -623,23 +689,13 @@ AUPluginUI::parent_cocoa_window () return 0; } -static void -dump_view_tree (NSView* view, int depth) +void +AUPluginUI::grab_focus() { - NSArray* subviews = [view subviews]; - unsigned long cnt = [subviews count]; - - for (int d = 0; d < depth; d++) { - cerr << '\t'; - } - cerr << " view @ " << view << endl; - - for (unsigned long i = 0; i < cnt; ++i) { - NSView* subview = [subviews objectAtIndex:i]; - dump_view_tree (subview, depth+1); + if (au_view) { + [au_view becomeFirstResponder]; } } - void AUPluginUI::forward_key_event (GdkEventKey* ev) { @@ -659,15 +715,6 @@ AUPluginUI::forward_key_event (GdkEventKey* ev) } else if ([nsevent type] == NSFlagsChanged) { [[[au_view window] firstResponder] flagsChanged:nsevent]; } - - NSRect frame = [au_view frame]; - if (ev->keyval == GDK_Down || ev->keyval == GDK_downarrow) { - frame.size.height += 1; - } else if (ev->keyval == GDK_Up || ev->keyval == GDK_uparrow) { - frame.size.height -= 1; - } - [au_view setFrameSize:frame.size]; - } } @@ -680,7 +727,7 @@ AUPluginUI::on_realize () NSWindow* win = get_nswindow (); if (win) { - [win setShowsResizeIndicator:NO]; + [win setShowsResizeIndicator:0]; } } @@ -695,8 +742,15 @@ AUPluginUI::lower_box_realized () } bool -AUPluginUI::on_map_event (GdkEventAny*) +AUPluginUI::lower_box_visibility_notify (GdkEventVisibility* ev) { +#ifdef WITH_CARBON + if (carbon_window && ev->state != GDK_VISIBILITY_UNOBSCURED) { + ShowWindow (carbon_window); + ActivateWindow (carbon_window, TRUE); + return true; + } +#endif return false; } @@ -709,8 +763,14 @@ AUPluginUI::on_window_hide () ActivateWindow (carbon_window, FALSE); } #endif - hide_all (); + +#if 0 + NSArray* wins = [NSApp windows]; + for (uint32_t i = 0; i < [wins count]; i++) { + id win = [wins objectAtIndex:i]; + } +#endif } bool @@ -752,19 +812,4 @@ create_au_gui (boost::shared_ptr plugin_insert, VBox** box) return aup; } -bool -AUPluginUI::on_focus_in_event (GdkEventFocus*) -{ - //cerr << "au plugin focus in\n"; - //Keyboard::magic_widget_grab_focus (); - return false; -} - -bool -AUPluginUI::on_focus_out_event (GdkEventFocus*) -{ - //cerr << "au plugin focus out\n"; - //Keyboard::magic_widget_drop_focus (); - return false; -}