diff --git a/flowcanvas/flowcanvas/FlowCanvas.h b/flowcanvas/flowcanvas/FlowCanvas.h index e78deee9..49c00414 100644 --- a/flowcanvas/flowcanvas/FlowCanvas.h +++ b/flowcanvas/flowcanvas/FlowCanvas.h @@ -50,7 +50,7 @@ class Module; * * \ingroup FlowCanvas */ -class FlowCanvas : public /*CANVASBASE*/Gnome::Canvas::CanvasAA +class FlowCanvas : public /*CANVASBASE*/Gnome::Canvas::Canvas // The CANVASBASE is a hook for a sed script in configure.ac { public: diff --git a/flowcanvas/flowcanvas/Module.h b/flowcanvas/flowcanvas/Module.h index 34edd0c8..9d2f0eff 100644 --- a/flowcanvas/flowcanvas/Module.h +++ b/flowcanvas/flowcanvas/Module.h @@ -55,8 +55,9 @@ public: void move(double dx, double dy); virtual void move_to(double x, double y); - bool is_within(const Gnome::Canvas::Rect* rect); - bool point_is_within(double x, double y); + bool is_within(const Gnome::Canvas::Rect* rect); + bool point_is_within(double x, double y); + boost::shared_ptr port_at(double x, double y); virtual void load_location() {} virtual void store_location() {} @@ -121,10 +122,12 @@ private: typedef multimap > ModuleMap; +// Performance critical functions: + + /** Find a port on this module. * - * Profiling has shown this to be performance critical, hence the inlining. - * Making this faster would be a very good idea - better data structure? + * TODO: Make this faster. */ inline boost::shared_ptr Module::get_port(const string& port_name) const @@ -135,6 +138,15 @@ Module::get_port(const string& port_name) const } +/** Returns whether or not the point @a x, @a y (world units) is within the module. + */ +inline bool +Module::point_is_within(double x, double y) +{ + return (x > property_x() && x < property_x() + m_width + && y > property_y() && y < property_y() + m_height); +} + } // namespace LibFlowCanvas diff --git a/flowcanvas/src/FlowCanvas.cpp b/flowcanvas/src/FlowCanvas.cpp index df00ed00..a38d72ae 100644 --- a/flowcanvas/src/FlowCanvas.cpp +++ b/flowcanvas/src/FlowCanvas.cpp @@ -987,41 +987,14 @@ FlowCanvas::connection_drag_handler(GdkEvent* event) boost::shared_ptr FlowCanvas::get_port_at(double x, double y) { - /* - Gnome::Canvas::Item* item = get_item_at(x, y); - - Port* const port_ptr = dynamic_cast(item); - - if (port_ptr) { - for (ModuleMap::iterator i = m_modules.begin(); i != m_modules.end(); ++i) { - const boost::shared_ptr module = (*i).second; - for (PortVector::const_iterator p = module->ports().begin(); p != module->ports().end(); ++p) { - const boost::shared_ptr port = (*p); - if (port && port.get() == port_ptr) - return port; - } - } - }*/ - // Loop through every port and see if the item at these coordinates is that port // (if you're thinking this is slow, stupid, and disgusting, you're right) - for (ModuleMap::iterator i = m_modules.begin(); i != m_modules.end(); ++i) { + for (ModuleMap::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i) { const boost::shared_ptr m = (*i).second; - if (m->point_is_within(x, y)) { - cerr << "Module at (" << x << ", " << y << "): " << m->name() << endl; - } - /*for (PortList::iterator j = (*i).second->ports().begin(); j != (*i).second->ports().end(); ++j) { - p = (*j); + + if (m->point_is_within(x, y)) + return m->port_at(x, y); - if ((Gnome::Canvas::Item*)p == item - || (Gnome::Canvas::Item*)(p->rect()) == item - || (Gnome::Canvas::Item*)(p->label()) == item) { - return p; - - - - } - }*/ } return boost::shared_ptr(); } diff --git a/flowcanvas/src/Module.cpp b/flowcanvas/src/Module.cpp index 50ae2b02..6c26aa86 100644 --- a/flowcanvas/src/Module.cpp +++ b/flowcanvas/src/Module.cpp @@ -247,17 +247,28 @@ Module::set_selected(bool selected) } -/** Returns whether or not the point @a x, @a y (world units) is within the module. +/** Get the port on this module at world coordinate @a x @a y. */ -bool -Module::point_is_within(double x, double y) +boost::shared_ptr +Module::port_at(double x, double y) { - const double x1 = m_module_box.property_x1(); - const double y1 = m_module_box.property_y1(); - const double x2 = m_module_box.property_x2(); - const double y2 = m_module_box.property_y2(); + x -= property_x(); + y -= property_y(); - return (x > x1 && x < x2 && y > y1 && y < y2); + for (PortVector::iterator p = m_ports.begin(); p != m_ports.end(); ++p) { + boost::shared_ptr port = *p; + if (x > port->property_x() && x < port->property_x() + port->width() + && y > port->property_y() && y < port->property_y() + port->height()) { + std::cerr << "HIT: " << name() << ":" << port->name() << std::endl; + return port; + } else { + std::cerr << "MISS: (" << x << ", " << y << ") not within " << + name() << ":" << port->name() << "(" << port->property_x() << ", " + << port->property_y() << ")" << std::endl; + } + } + + return boost::shared_ptr(); } @@ -480,7 +491,9 @@ Module::resize() } -/** Port offset, for connection drawing. See doc/port_offsets.dia */ +/** Port offset, for connection drawing. + * See doc/port_offsets.dia + */ double Module::port_connection_point_offset(boost::shared_ptr port) { @@ -491,7 +504,9 @@ Module::port_connection_point_offset(boost::shared_ptr port) } -/** Range of port offsets, for connection drawing. See doc/port_offsets.dia */ +/** Range of port offsets, for connection drawing. + * See doc/port_offsets.dia + */ double Module::port_connection_points_range() { diff --git a/patchage/src/PatchagePort.h b/patchage/src/PatchagePort.h index 7ebc9950..ec069a3d 100644 --- a/patchage/src/PatchagePort.h +++ b/patchage/src/PatchagePort.h @@ -22,6 +22,7 @@ #include #include #include +#include using namespace LibFlowCanvas; using std::string; using std::list;