diff --git a/gtk2_ardour/mac_vst_plugin_ui.h b/gtk2_ardour/mac_vst_plugin_ui.h index 2082fa8578..535a0c2212 100644 --- a/gtk2_ardour/mac_vst_plugin_ui.h +++ b/gtk2_ardour/mac_vst_plugin_ui.h @@ -34,6 +34,14 @@ #include "vst_plugin_ui.h" +class MacVSTPluginUI; + +@interface ResizeNotificationObject : NSObject { + @private + MacVSTPluginUI* plugin_ui; +} +@end + class MacVSTPluginUI : public VSTPluginUI { public: @@ -46,11 +54,19 @@ public: int package (Gtk::Window &); void forward_key_event (GdkEventKey *); + void view_resized (); + +protected: + void lower_box_realized (); + bool lower_box_visibility_notify (GdkEventVisibility*); + void lower_box_map (); + void lower_box_unmap (); + void lower_box_size_request (GtkRequisition*); + void lower_box_size_allocate (Gtk::Allocation&); private: int get_XID (); bool idle (); - void lower_box_realized (); void set_program (); NSWindow* get_nswindow(); @@ -58,4 +74,5 @@ private: NSView* _ns_view; sigc::connection _idle_connection; PBD::ScopedConnection _program_connection; + ResizeNotificationObject* _resize_notifier; }; diff --git a/gtk2_ardour/mac_vst_plugin_ui.mm b/gtk2_ardour/mac_vst_plugin_ui.mm index 5a20af8036..6297525d16 100644 --- a/gtk2_ardour/mac_vst_plugin_ui.mm +++ b/gtk2_ardour/mac_vst_plugin_ui.mm @@ -40,6 +40,24 @@ struct ERect{ short right; }; + +@implementation ResizeNotificationObject + +- (ResizeNotificationObject*) initWithPluginUI: (MacVSTPluginUI*) vstui +{ + self = [ super init ]; + plugin_ui = vstui; + return self; +} + +- (void)viewResized:(NSNotification *)notification +{ + (void) notification; // unused + plugin_ui->view_resized(); +} + +@end + VSTPluginUI* create_mac_vst_gui (boost::shared_ptr insert) { @@ -55,18 +73,45 @@ MacVSTPluginUI::MacVSTPluginUI (boost::shared_ptr pi, boost::share { low_box.add_events (Gdk::VISIBILITY_NOTIFY_MASK | Gdk::EXPOSURE_MASK); low_box.signal_realize().connect (mem_fun (this, &MacVSTPluginUI::lower_box_realized)); + low_box.signal_visibility_notify_event ().connect (mem_fun (this, &MacVSTPluginUI::lower_box_visibility_notify)); + low_box.signal_size_request ().connect (mem_fun (this, &MacVSTPluginUI::lower_box_size_request)); + low_box.signal_size_allocate ().connect (mem_fun (this, &MacVSTPluginUI::lower_box_size_allocate)); + low_box.signal_map ().connect (mem_fun (this, &MacVSTPluginUI::lower_box_map)); + low_box.signal_unmap ().connect (mem_fun (this, &MacVSTPluginUI::lower_box_unmap)); + pack_start (low_box, true, true); low_box.show (); + vst->LoadPresetProgram.connect (_program_connection, invalidator (*this), boost::bind (&MacVSTPluginUI::set_program, this), gui_context()); + _ns_view = [[NSView new] retain]; + + AEffect* plugin = _vst->state()->plugin; + plugin->dispatcher (plugin, effEditOpen, 0, 0, _ns_view, 0.0f); + _idle_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &MacVSTPluginUI::idle)); + + _resize_notifier = [[ResizeNotificationObject alloc] initWithPluginUI:this]; + [[NSNotificationCenter defaultCenter] addObserver:_resize_notifier + selector:@selector(viewResized:) name:NSViewFrameDidChangeNotification + object:_ns_view]; + + NSArray* subviews = [_ns_view subviews]; + assert ([subviews count] < 2); + for (unsigned long i = 0; i < [subviews count]; ++i) { + NSView* subview = [subviews objectAtIndex:i]; + [[NSNotificationCenter defaultCenter] addObserver:_resize_notifier + selector:@selector(viewResized:) name:NSViewFrameDidChangeNotification + object:subview]; + } } MacVSTPluginUI::~MacVSTPluginUI () { - if (_ns_view) { - [_ns_view removeFromSuperview]; - [_ns_view release]; - } + [[NSNotificationCenter defaultCenter] removeObserver:_resize_notifier]; + [_resize_notifier release]; + + [_ns_view removeFromSuperview]; + [_ns_view release]; AEffect* plugin = _vst->state()->plugin; plugin->dispatcher (plugin, effEditClose, 0, 0, 0, 0.0f); @@ -114,35 +159,68 @@ MacVSTPluginUI::lower_box_realized () [win setAutodisplay:1]; // turn off GTK stuff for this window NSView* view = gdk_quartz_window_get_nsview (low_box.get_window()->gobj()); - _ns_view = [[NSView new] retain]; [view addSubview:_ns_view]; + low_box.queue_resize (); +} - AEffect* plugin = _vst->state()->plugin; - plugin->dispatcher (plugin, effEditOpen, 0, 0, _ns_view, 0.0f); +bool +MacVSTPluginUI::lower_box_visibility_notify (GdkEventVisibility* ev) +{ + return false; +} +void +MacVSTPluginUI::lower_box_map () +{ + [_ns_view setHidden:0]; +} +void +MacVSTPluginUI::lower_box_unmap () +{ + [_ns_view setHidden:1]; +} + +void +MacVSTPluginUI::lower_box_size_request (GtkRequisition* requisition) +{ struct ERect* er = NULL; + AEffect* plugin = _vst->state()->plugin; plugin->dispatcher (plugin, effEditGetRect, 0, 0, &er, 0 ); if (er) { - int req_width = er->right - er->left; - int req_height = er->bottom - er->top; - - low_box.set_size_request (req_width, req_height); - - gint xx, yy; - gtk_widget_translate_coordinates( - GTK_WIDGET(low_box.gobj()), - GTK_WIDGET(low_box.get_parent()->gobj()), - 8, 6, &xx, &yy); - [_ns_view setFrame:NSMakeRect(xx, yy, req_width, req_height)]; + requisition->width = er->right - er->left; + requisition->height = er->bottom - er->top; + } else { + requisition->width = 600; + requisition->height = 400; } +} - _idle_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &MacVSTPluginUI::idle)); +void +MacVSTPluginUI::lower_box_size_allocate (Gtk::Allocation& allocation) +{ + gint xx, yy; + gtk_widget_translate_coordinates( + GTK_WIDGET(low_box.gobj()), + GTK_WIDGET(low_box.get_parent()->gobj()), + 8, 6, &xx, &yy); + [_ns_view setFrame:NSMakeRect (xx, yy, allocation.get_width (), allocation.get_height ())]; + NSArray* subviews = [_ns_view subviews]; + for (unsigned long i = 0; i < [subviews count]; ++i) { + NSView* subview = [subviews objectAtIndex:i]; + [subview setFrame:NSMakeRect (0, 0, allocation.get_width (), allocation.get_height ())]; + } +} + +void +MacVSTPluginUI::view_resized () +{ + low_box.queue_resize (); } int MacVSTPluginUI::get_XID () { - return _vst->state()->xid; + return _vst->state()->xid; // unused } bool