Working connection dragging/snap/etc.

git-svn-id: http://svn.drobilla.net/lad@149 a436a847-0d15-0410-975c-d299462d15a1
This commit is contained in:
dave 2006-10-03 01:04:11 +00:00
parent 18c868c336
commit 0e245b564a
5 changed files with 47 additions and 46 deletions

View File

@ -50,7 +50,7 @@ class Module;
* *
* \ingroup FlowCanvas * \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 // The CANVASBASE is a hook for a sed script in configure.ac
{ {
public: public:

View File

@ -55,8 +55,9 @@ public:
void move(double dx, double dy); void move(double dx, double dy);
virtual void move_to(double x, double y); virtual void move_to(double x, double y);
bool is_within(const Gnome::Canvas::Rect* rect); bool is_within(const Gnome::Canvas::Rect* rect);
bool point_is_within(double x, double y); bool point_is_within(double x, double y);
boost::shared_ptr<Port> port_at(double x, double y);
virtual void load_location() {} virtual void load_location() {}
virtual void store_location() {} virtual void store_location() {}
@ -121,10 +122,12 @@ private:
typedef multimap<string,boost::shared_ptr<Module> > ModuleMap; typedef multimap<string,boost::shared_ptr<Module> > ModuleMap;
// Performance critical functions:
/** Find a port on this module. /** Find a port on this module.
* *
* Profiling has shown this to be performance critical, hence the inlining. * TODO: Make this faster.
* Making this faster would be a very good idea - better data structure?
*/ */
inline boost::shared_ptr<Port> inline boost::shared_ptr<Port>
Module::get_port(const string& port_name) const 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 } // namespace LibFlowCanvas

View File

@ -987,41 +987,14 @@ FlowCanvas::connection_drag_handler(GdkEvent* event)
boost::shared_ptr<Port> boost::shared_ptr<Port>
FlowCanvas::get_port_at(double x, double y) FlowCanvas::get_port_at(double x, double y)
{ {
/*
Gnome::Canvas::Item* item = get_item_at(x, y);
Port* const port_ptr = dynamic_cast<Port*>(item);
if (port_ptr) {
for (ModuleMap::iterator i = m_modules.begin(); i != m_modules.end(); ++i) {
const boost::shared_ptr<Module> module = (*i).second;
for (PortVector::const_iterator p = module->ports().begin(); p != module->ports().end(); ++p) {
const boost::shared_ptr<Port> 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 // 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) // (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<Module> m = (*i).second; const boost::shared_ptr<Module> m = (*i).second;
if (m->point_is_within(x, y)) {
cerr << "Module at (" << x << ", " << y << "): " << m->name() << endl; if (m->point_is_within(x, y))
} return m->port_at(x, y);
/*for (PortList::iterator j = (*i).second->ports().begin(); j != (*i).second->ports().end(); ++j) {
p = (*j);
if ((Gnome::Canvas::Item*)p == item
|| (Gnome::Canvas::Item*)(p->rect()) == item
|| (Gnome::Canvas::Item*)(p->label()) == item) {
return p;
}
}*/
} }
return boost::shared_ptr<Port>(); return boost::shared_ptr<Port>();
} }

View File

@ -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 boost::shared_ptr<Port>
Module::point_is_within(double x, double y) Module::port_at(double x, double y)
{ {
const double x1 = m_module_box.property_x1(); x -= property_x();
const double y1 = m_module_box.property_y1(); y -= property_y();
const double x2 = m_module_box.property_x2();
const double y2 = m_module_box.property_y2();
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> 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<Port>();
} }
@ -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 double
Module::port_connection_point_offset(boost::shared_ptr<Port> port) Module::port_connection_point_offset(boost::shared_ptr<Port> port)
{ {
@ -491,7 +504,9 @@ Module::port_connection_point_offset(boost::shared_ptr<Port> 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 double
Module::port_connection_points_range() Module::port_connection_points_range()
{ {

View File

@ -22,6 +22,7 @@
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <flowcanvas/Port.h> #include <flowcanvas/Port.h>
#include <flowcanvas/Module.h> #include <flowcanvas/Module.h>
#include <boost/shared_ptr.hpp>
using namespace LibFlowCanvas; using namespace LibFlowCanvas;
using std::string; using std::list; using std::string; using std::list;