+PluginPinDialog::darea_size_request (Gtk::Requisition* req)
+{
+ req->width = _min_width;
+ req->height = 200;
+}
+
+void
+PluginPinDialog::darea_size_allocate (Gtk::Allocation&)
+{
+ _position_valid = false;
+}
+
+bool
+PluginPinDialog::darea_motion_notify_event (GdkEventMotion* ev)
+{
+ bool changed = false;
+ _hover.reset ();
+ for (CtrlElemList::iterator i = _elements.begin (); i != _elements.end (); ++i) {
+ if (ev->x >= i->x && ev->x <= i->x + i->w
+ && ev->y >= i->y && ev->y <= i->y + i->h)
+ {
+ if (!i->prelight) changed = true;
+ i->prelight = true;
+ _hover = i->e;
+ } else {
+ if (i->prelight) changed = true;
+ i->prelight = false;
+ }
+ }
+ if (changed) {
+ darea.queue_draw ();
+ }
+ return true;
+}
+
+bool
+PluginPinDialog::darea_button_press_event (GdkEventButton* ev)
+{
+ if (ev->type != GDK_BUTTON_PRESS) {
+ return false;
+ }
+
+ switch (ev->button) {
+ case 1:
+ if (!_selection || (_selection && !_hover)) {
+ _selection = _hover;
+ _actor.reset ();
+ darea.queue_draw ();
+ } else if (_selection && _hover && _selection != _hover) {
+ if (_selection->dt != _hover->dt) { _actor.reset (); }
+ else if (_selection->ct == Input && _hover->ct == Sink) { _actor = _hover; }
+ else if (_selection->ct == Sink && _hover->ct == Input) { _actor = _hover; }
+ else if (_selection->ct == Output && _hover->ct == Source) { _actor = _hover; }
+ else if (_selection->ct == Source && _hover->ct == Output) { _actor = _hover; }
+ if (!_actor) {
+ _selection = _hover;
+ }
+ darea.queue_draw ();
+ }
+ case 3:
+ if (_hover) {
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool
+PluginPinDialog::darea_button_release_event (GdkEventButton* ev)
+{
+ if (_hover == _actor && _actor) {
+ assert (_selection);
+ assert (_selection->dt == _actor->dt);
+ if (_selection->ct == Input && _actor->ct == Sink) {
+ handle_input_action (_actor, _selection);
+ }
+ else if (_selection->ct == Sink && _actor->ct == Input) {
+ handle_input_action (_selection, _actor);
+ }
+ else if (_selection->ct == Output && _actor->ct == Source) {
+ handle_output_action (_actor, _selection);
+ }
+ else if (_selection->ct == Source && _actor->ct == Output) {
+ handle_output_action (_selection, _actor);
+ }
+ _selection.reset ();
+ }
+ _actor.reset ();
+ darea.queue_draw ();
+ return true;
+}
+
+void
+PluginPinDialog::handle_input_action (const CtrlElem &s, const CtrlElem &i)
+{
+ const int pc = s->ip;
+ bool valid;
+ ChanMapping in_map (_pi->input_map (pc));
+ uint32_t idx = in_map.get (s->dt, s->id, &valid);
+
+ if (valid && idx == i->id) {
+ // disconnect
+ in_map.unset (s->dt, s->id);
+ _pi->set_input_map (pc, in_map);
+ }
+ else if (!valid) {
+ // connect
+ in_map.set (s->dt, s->id, i->id);
+ _pi->set_input_map (pc, in_map);
+ }
+ else {
+ // reconnect
+ in_map.unset (s->dt, s->id);
+ in_map.set (s->dt, s->id, i->id);
+ _pi->set_input_map (pc, in_map);
+ }
+}
+
+void
+PluginPinDialog::handle_output_action (const CtrlElem &s, const CtrlElem &o)
+{
+ const uint32_t pc = s->ip;
+ bool valid;
+ ChanMapping out_map (_pi->output_map (pc));
+ uint32_t idx = out_map.get (s->dt, s->id, &valid);
+
+ if (valid && idx == o->id) {
+ // disconnect
+ out_map.unset (s->dt, s->id);
+ _pi->set_output_map (pc, out_map);
+ }
+ else {
+ // disconnect source
+ if (valid) {
+ out_map.unset (s->dt, s->id);
+ }
+ // disconnect other outputs
+ _ignore_updates = true;
+ for (uint32_t n = 0; n < _n_plugins; ++n) {
+ if (n == pc) {
+ continue;
+ }
+ ChanMapping n_out_map (_pi->output_map (n));
+ idx = n_out_map.get_src (s->dt, o->id, &valid);
+ if (valid) {
+ n_out_map.unset (s->dt, idx);
+ _pi->set_output_map (n, n_out_map);
+ }
+ }
+ _ignore_updates = false;
+ idx = out_map.get_src (s->dt, o->id, &valid);
+ if (valid) {
+ out_map.unset (s->dt, idx);
+ }
+ // connect
+ out_map.set (s->dt, s->id, o->id);
+ _pi->set_output_map (pc, out_map);
+ }
+}
+
+void
+PluginPinDialog::reset_configuration ()
+{
+ _route ()->reset_plugin_insert (_pi);
+}
+
+void
+PluginPinDialog::reset_mapping ()