diff options
Diffstat (limited to 'src/Canvas.cpp')
-rw-r--r-- | src/Canvas.cpp | 382 |
1 files changed, 189 insertions, 193 deletions
diff --git a/src/Canvas.cpp b/src/Canvas.cpp index 306c62f..30212c7 100644 --- a/src/Canvas.cpp +++ b/src/Canvas.cpp @@ -56,293 +56,289 @@ PATCHAGE_RESTORE_WARNINGS namespace patchage { Canvas::Canvas(Connector& connector, int width, int height) - : Ganv::Canvas(width, height) - , _connector(connector) + : Ganv::Canvas(width, height) + , _connector(connector) { - signal_event.connect(sigc::mem_fun(this, &Canvas::on_event)); - signal_connect.connect(sigc::mem_fun(this, &Canvas::on_connect)); - signal_disconnect.connect(sigc::mem_fun(this, &Canvas::on_disconnect)); + signal_event.connect(sigc::mem_fun(this, &Canvas::on_event)); + signal_connect.connect(sigc::mem_fun(this, &Canvas::on_connect)); + signal_disconnect.connect(sigc::mem_fun(this, &Canvas::on_disconnect)); } CanvasPort* Canvas::create_port(Patchage& patchage, const PortID& id, const PortInfo& info) { - const auto client_id = id.client(); - - const auto port_name = - ((id.type() == PortID::Type::alsa) ? info.label : PortNames(id).port()); - - // Figure out the client name, for ALSA we need the metadata cache - std::string client_name; - if (id.type() == PortID::Type::alsa) { - const auto client_info = patchage.metadata().client(client_id); - if (!client_info) { - patchage.log().error(fmt::format( - R"(Unable to add port "{}", client "{}" is unknown)", - id, - client_id)); - - return nullptr; - } - - client_name = client_info->label; - } else { - client_name = PortNames(id).client(); - } - - // Determine the module type to place the port on in case of splitting - SignalDirection module_type = SignalDirection::duplex; - if (patchage.conf().get_module_split(client_name, info.is_terminal)) { - module_type = info.direction; - } - - // Find or create parent module - CanvasModule* parent = find_module(client_id, module_type); - if (!parent) { - parent = - new CanvasModule(&patchage, client_name, module_type, client_id); - - parent->load_location(); - add_module(client_id, parent); - } - - if (parent->get_port(id)) { - // TODO: Update existing port? - patchage.log().error(fmt::format( - R"(Module "{}" already has port "{}")", client_name, port_name)); - return nullptr; - } - - auto* const port = new CanvasPort(*parent, - info.type, - id, - port_name, - info.label, - info.direction == SignalDirection::input, - patchage.conf().get_port_color(info.type), - patchage.show_human_names(), - info.order); - - _port_index.insert(std::make_pair(id, port)); - - return port; + const auto client_id = id.client(); + + const auto port_name = + ((id.type() == PortID::Type::alsa) ? info.label : PortNames(id).port()); + + // Figure out the client name, for ALSA we need the metadata cache + std::string client_name; + if (id.type() == PortID::Type::alsa) { + const auto client_info = patchage.metadata().client(client_id); + if (!client_info) { + patchage.log().error(fmt::format( + R"(Unable to add port "{}", client "{}" is unknown)", id, client_id)); + + return nullptr; + } + + client_name = client_info->label; + } else { + client_name = PortNames(id).client(); + } + + // Determine the module type to place the port on in case of splitting + SignalDirection module_type = SignalDirection::duplex; + if (patchage.conf().get_module_split(client_name, info.is_terminal)) { + module_type = info.direction; + } + + // Find or create parent module + CanvasModule* parent = find_module(client_id, module_type); + if (!parent) { + parent = new CanvasModule(&patchage, client_name, module_type, client_id); + + parent->load_location(); + add_module(client_id, parent); + } + + if (parent->get_port(id)) { + // TODO: Update existing port? + patchage.log().error(fmt::format( + R"(Module "{}" already has port "{}")", client_name, port_name)); + return nullptr; + } + + auto* const port = new CanvasPort(*parent, + info.type, + id, + port_name, + info.label, + info.direction == SignalDirection::input, + patchage.conf().get_port_color(info.type), + patchage.show_human_names(), + info.order); + + _port_index.insert(std::make_pair(id, port)); + + return port; } CanvasModule* Canvas::find_module(const ClientID& id, const SignalDirection type) { - auto i = _module_index.find(id); + auto i = _module_index.find(id); - CanvasModule* io_module = nullptr; - for (; i != _module_index.end() && i->first == id; ++i) { - if (i->second->type() == type) { - return i->second; - } + CanvasModule* io_module = nullptr; + for (; i != _module_index.end() && i->first == id; ++i) { + if (i->second->type() == type) { + return i->second; + } - if (i->second->type() == SignalDirection::duplex) { - io_module = i->second; - } - } + if (i->second->type() == SignalDirection::duplex) { + io_module = i->second; + } + } - // Return InputOutput module for Input or Output (or nullptr if not found) - return io_module; + // Return InputOutput module for Input or Output (or nullptr if not found) + return io_module; } void Canvas::remove_module(const ClientID& id) { - auto i = _module_index.find(id); - while (i != _module_index.end()) { - CanvasModule* mod = i->second; - _module_index.erase(i); - i = _module_index.find(id); - delete mod; - } + auto i = _module_index.find(id); + while (i != _module_index.end()) { + CanvasModule* mod = i->second; + _module_index.erase(i); + i = _module_index.find(id); + delete mod; + } } CanvasPort* Canvas::find_port(const PortID& id) { - auto i = _port_index.find(id); - if (i != _port_index.end()) { - assert(i->second->get_module()); - return i->second; - } + auto i = _port_index.find(id); + if (i != _port_index.end()) { + assert(i->second->get_module()); + return i->second; + } - return nullptr; + return nullptr; } void Canvas::remove_port(const PortID& id) { - CanvasPort* const port = find_port(id); - _port_index.erase(id); - delete port; + CanvasPort* const port = find_port(id); + _port_index.erase(id); + delete port; } -struct RemovePortsData -{ - using Predicate = bool (*)(const CanvasPort*); +struct RemovePortsData { + using Predicate = bool (*)(const CanvasPort*); - explicit RemovePortsData(Predicate p) - : pred(p) - {} + explicit RemovePortsData(Predicate p) + : pred(p) + {} - Predicate pred; - std::set<CanvasModule*> empty; + Predicate pred; + std::set<CanvasModule*> empty; }; static void delete_port_if_matches(GanvPort* port, void* cdata) { - auto* data = static_cast<RemovePortsData*>(cdata); - auto* pport = dynamic_cast<CanvasPort*>(Glib::wrap(port)); - if (pport && data->pred(pport)) { - delete pport; - } + auto* data = static_cast<RemovePortsData*>(cdata); + auto* pport = dynamic_cast<CanvasPort*>(Glib::wrap(port)); + if (pport && data->pred(pport)) { + delete pport; + } } static void remove_ports_matching(GanvNode* node, void* cdata) { - if (!GANV_IS_MODULE(node)) { - return; - } + if (!GANV_IS_MODULE(node)) { + return; + } - Ganv::Module* cmodule = Glib::wrap(GANV_MODULE(node)); - auto* pmodule = dynamic_cast<CanvasModule*>(cmodule); - if (!pmodule) { - return; - } + Ganv::Module* cmodule = Glib::wrap(GANV_MODULE(node)); + auto* pmodule = dynamic_cast<CanvasModule*>(cmodule); + if (!pmodule) { + return; + } - auto* data = static_cast<RemovePortsData*>(cdata); + auto* data = static_cast<RemovePortsData*>(cdata); - pmodule->for_each_port(delete_port_if_matches, data); + pmodule->for_each_port(delete_port_if_matches, data); - if (pmodule->num_ports() == 0) { - data->empty.insert(pmodule); - } + if (pmodule->num_ports() == 0) { + data->empty.insert(pmodule); + } } void Canvas::remove_ports(bool (*pred)(const CanvasPort*)) { - RemovePortsData data(pred); - - for_each_node(remove_ports_matching, &data); - - for (auto i = _port_index.begin(); i != _port_index.end();) { - auto next = i; - ++next; - if (pred(i->second)) { - _port_index.erase(i); - } - i = next; - } - - for (CanvasModule* m : data.empty) { - delete m; - } + RemovePortsData data(pred); + + for_each_node(remove_ports_matching, &data); + + for (auto i = _port_index.begin(); i != _port_index.end();) { + auto next = i; + ++next; + if (pred(i->second)) { + _port_index.erase(i); + } + i = next; + } + + for (CanvasModule* m : data.empty) { + delete m; + } } void Canvas::on_connect(Ganv::Node* port1, Ganv::Node* port2) { - auto* const p1 = dynamic_cast<CanvasPort*>(port1); - auto* const p2 = dynamic_cast<CanvasPort*>(port2); - - if (p1 && p2) { - if (p1->is_output() && p2->is_input()) { - _connector.connect(p1->id(), p2->id()); - } else if (p2->is_output() && p1->is_input()) { - _connector.connect(p2->id(), p1->id()); - } - } + auto* const p1 = dynamic_cast<CanvasPort*>(port1); + auto* const p2 = dynamic_cast<CanvasPort*>(port2); + + if (p1 && p2) { + if (p1->is_output() && p2->is_input()) { + _connector.connect(p1->id(), p2->id()); + } else if (p2->is_output() && p1->is_input()) { + _connector.connect(p2->id(), p1->id()); + } + } } void Canvas::on_disconnect(Ganv::Node* port1, Ganv::Node* port2) { - auto* const p1 = dynamic_cast<CanvasPort*>(port1); - auto* const p2 = dynamic_cast<CanvasPort*>(port2); - - if (p1 && p2) { - if (p1->is_output() && p2->is_input()) { - _connector.disconnect(p1->id(), p2->id()); - } else if (p2->is_output() && p1->is_input()) { - _connector.disconnect(p2->id(), p1->id()); - } - } + auto* const p1 = dynamic_cast<CanvasPort*>(port1); + auto* const p2 = dynamic_cast<CanvasPort*>(port2); + + if (p1 && p2) { + if (p1->is_output() && p2->is_input()) { + _connector.disconnect(p1->id(), p2->id()); + } else if (p2->is_output() && p1->is_input()) { + _connector.disconnect(p2->id(), p1->id()); + } + } } void Canvas::add_module(const ClientID& id, CanvasModule* module) { - _module_index.emplace(id, module); - - // Join partners, if applicable - CanvasModule* in_module = nullptr; - CanvasModule* out_module = nullptr; - if (module->type() == SignalDirection::input) { - in_module = module; - out_module = find_module(id, SignalDirection::output); - } else if (module->type() == SignalDirection::output) { - in_module = find_module(id, SignalDirection::input); - out_module = module; - } - - if (in_module && out_module) { - out_module->set_partner(in_module); - } + _module_index.emplace(id, module); + + // Join partners, if applicable + CanvasModule* in_module = nullptr; + CanvasModule* out_module = nullptr; + if (module->type() == SignalDirection::input) { + in_module = module; + out_module = find_module(id, SignalDirection::output); + } else if (module->type() == SignalDirection::output) { + in_module = find_module(id, SignalDirection::input); + out_module = module; + } + + if (in_module && out_module) { + out_module->set_partner(in_module); + } } void disconnect_edge(GanvEdge* edge, void* data) { - auto* canvas = static_cast<Canvas*>(data); - Ganv::Edge* edgemm = Glib::wrap(edge); - canvas->on_disconnect(edgemm->get_tail(), edgemm->get_head()); + auto* canvas = static_cast<Canvas*>(data); + Ganv::Edge* edgemm = Glib::wrap(edge); + canvas->on_disconnect(edgemm->get_tail(), edgemm->get_head()); } bool Canvas::on_event(GdkEvent* ev) { - if (ev->type == GDK_KEY_PRESS && ev->key.keyval == GDK_KEY_Delete) { - for_each_selected_edge(disconnect_edge, this); - clear_selection(); - return true; - } + if (ev->type == GDK_KEY_PRESS && ev->key.keyval == GDK_KEY_Delete) { + for_each_selected_edge(disconnect_edge, this); + clear_selection(); + return true; + } - return false; + return false; } bool Canvas::make_connection(Ganv::Node* tail, Ganv::Node* head) { - new Ganv::Edge(*this, tail, head); - return true; + new Ganv::Edge(*this, tail, head); + return true; } void Canvas::remove_module(CanvasModule* module) { - // Remove module from cache - for (auto i = _module_index.find(module->id()); - i != _module_index.end() && i->first == module->id(); - ++i) { - if (i->second == module) { - _module_index.erase(i); - return; - } - } + // Remove module from cache + for (auto i = _module_index.find(module->id()); + i != _module_index.end() && i->first == module->id(); + ++i) { + if (i->second == module) { + _module_index.erase(i); + return; + } + } } void Canvas::clear() { - _port_index.clear(); - _module_index.clear(); - Ganv::Canvas::clear(); + _port_index.clear(); + _module_index.clear(); + Ganv::Canvas::clear(); } } // namespace patchage |