tentative intermediate state for ArdourCanvas::Curve
[ardour.git] / libs / canvas / lookup_table.cc
index 8fbbbea98e0145c456fe7a76c948da91e12f7eff..f88531537aebb0544d85a792f6c749e8e9199dad 100644 (file)
@@ -1,3 +1,22 @@
+/*
+    Copyright (C) 2011-2013 Paul Davis
+    Author: Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
 #include "canvas/lookup_table.h"
 #include "canvas/group.h"
 
@@ -30,26 +49,49 @@ DumbLookupTable::get (Rect const &)
        return vitems;
 }
 
-/* XXX: what coordinate system is the point in? parent of our group I think */
 vector<Item *>
-DumbLookupTable::items_at_point (Duple point) const
+DumbLookupTable::items_at_point (Duple const & point) const
 {
-       list<Item *> items = _group.items ();
+       /* Point is in canvas coordinate system */
+
+       list<Item *> const & items (_group.items ());
        vector<Item *> vitems;
 
        for (list<Item *>::const_iterator i = items.begin(); i != items.end(); ++i) {
-               boost::optional<Rect> item_bbox = (*i)->bounding_box ();
-               if (item_bbox) {
-                       Rect parent_bbox = (*i)->item_to_parent (item_bbox.get ());
-                       if (parent_bbox.contains (point)) {
-                               vitems.push_back (*i);
-                       }
+
+               if ((*i)->covers (point)) {
+                       // std::cerr << "\t\t" << (*i)->whatami() << '/' << (*i)->name << " covers " << point << std::endl;
+                       vitems.push_back (*i);
                }
        }
 
        return vitems;
 }
 
+bool
+DumbLookupTable::has_item_at_point (Duple const & point) const
+{
+       /* Point is in canvas coordinate system */
+
+       list<Item *> const & items (_group.items ());
+       vector<Item *> vitems;
+
+       for (list<Item *>::const_iterator i = items.begin(); i != items.end(); ++i) {
+
+               if (!(*i)->visible()) {
+                       continue;
+               }
+               
+               if ((*i)->covers (point)) {
+                       // std::cerr << "\t\t" << (*i)->whatami() << '/' << (*i)->name << " covers " << point << std::endl;
+                       return true;
+                       
+               }
+       }
+
+       return false;
+}
+
 OptimizingLookupTable::OptimizingLookupTable (Group const & group, int items_per_cell)
        : LookupTable (group)
        , _items_per_cell (items_per_cell)
@@ -60,7 +102,7 @@ OptimizingLookupTable::OptimizingLookupTable (Group const & group, int items_per
        /* number of cells */
        int const cells = items.size() / _items_per_cell;
        /* hence number down each side of the table's square */
-       _dimension = max (1, int (rint (sqrt (cells))));
+       _dimension = max (1, int (rint (sqrt ((double)cells))));
 
        _cells = new Cell*[_dimension];
        for (int i = 0; i < _dimension; ++i) {
@@ -169,7 +211,7 @@ OptimizingLookupTable::point_to_indices (Duple point, int& x, int& y) const
 }
 
 vector<Item*>
-OptimizingLookupTable::items_at_point (Duple point) const
+OptimizingLookupTable::items_at_point (Duple const & point) const
 {
        int x;
        int y;
@@ -204,6 +246,43 @@ OptimizingLookupTable::items_at_point (Duple point) const
 
        return items;
 }
+
+bool
+OptimizingLookupTable::has_item_at_point (Duple const & point) const
+{
+       int x;
+       int y;
+       point_to_indices (point, x, y);
+
+       if (x >= _dimension) {
+               cout << "WARNING: x=" << x << ", dim=" << _dimension << ", px=" << point.x << " cellsize=" << _cell_size << "\n";
+       }
+
+       if (y >= _dimension) {
+               cout << "WARNING: y=" << y << ", dim=" << _dimension << ", py=" << point.y << " cellsize=" << _cell_size << "\n";
+       }
+       
+       /* XXX: hmm */
+       x = min (_dimension - 1, x);
+       y = min (_dimension - 1, y);
+
+       assert (x >= 0);
+       assert (y >= 0);
+
+       Cell const & cell = _cells[x][y];
+       vector<Item*> items;
+       for (Cell::const_iterator i = cell.begin(); i != cell.end(); ++i) {
+               boost::optional<Rect> const item_bbox = (*i)->bounding_box ();
+               if (item_bbox) {
+                       Rect parent_bbox = (*i)->item_to_parent (item_bbox.get ());
+                       if (parent_bbox.contains (point)) {
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
        
 /** @param area Area in our owning group's coordinates */
 vector<Item*>