Prefer const references for Pin/Channel maps
[ardour.git] / libs / canvas / grid.cc
index f8fd0bcce4626ca80535ba329edef16ebdb6e67a..e46a184e42ce19dd3a5d6e4be29da8a849a36960 100644 (file)
@@ -184,34 +184,35 @@ Grid::reposition_children ()
        uint32_t max_col = 0;
 
        /* since we encourage dynamic and essentially random placement of
-        * children, begin by determining the maximum row and column given
+        * children, begin by determining the maximum row and column extents given
         * our current set of children and placements.
         */
 
        for (CoordsByItem::const_iterator c = coords_by_item.begin(); c != coords_by_item.end(); ++c) {
-               max_col = max (max_col, (uint32_t) c->second.x);
-               max_row = max (max_row, (uint32_t) c->second.y);
+               if (collapse_on_hide && !c->second.item->visible()) {
+                       continue;
+               }
+               max_col = max (max_col, (uint32_t) (c->second.x + c->second.col_span));
+               max_row = max (max_row, (uint32_t) (c->second.y + c->second.row_span));
        }
 
-       max_row++;
-       max_col++;
-
        /* Now compute the width of the widest child for each column, and the
-        * height of the tallest child for each row.
+        * height of the tallest child for each row. Store the results in
+        * row_dimens and col_dimens, making sure they are suitably sized first.
         */
 
        vector<double> row_dimens;
        vector<double> col_dimens;
 
-       row_dimens.assign (max_row, 0);
-       col_dimens.assign (max_col, 0);
+       row_dimens.assign (max_row + 1, 0);
+       col_dimens.assign (max_col + 1, 0);
 
-       Rect uniform_size;
+       Rect uniform_cell_size;
 
        if (homogenous) {
                for (std::list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
 
-                       if (*i == bg) {
+                       if (*i == bg || (collapse_on_hide && !(*i)->visible())) {
                                continue;
                        }
 
@@ -220,30 +221,41 @@ Grid::reposition_children ()
                        if (!bb) {
                                continue;
                        }
-                       cerr << "\tbb for " << (*i)->whatami() << " is " << bb << endl;
-                       uniform_size.y1 = max (uniform_size.y1, bb.height());
-                       uniform_size.x1 = max (uniform_size.x1, bb.width());
+
+                       CoordsByItem::const_iterator c = coords_by_item.find (*i);
+
+                       uniform_cell_size.x1 = max (uniform_cell_size.x1, (bb.width()/c->second.col_span));
+                       uniform_cell_size.y1 = max (uniform_cell_size.y1, (bb.height()/c->second.row_span));
                }
 
-               cerr << "Uniform size will be " << uniform_size << endl;
+               for (uint32_t n = 0; n < max_col; ++n) {
+                       col_dimens[n] = uniform_cell_size.width();
+               }
+
+               for (uint32_t n = 0; n < max_row; ++n) {
+                       row_dimens[n] = uniform_cell_size.height();
+               }
 
                for (std::list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
-                       if (*i == bg) {
+
+                       if (*i == bg || (collapse_on_hide && !(*i)->visible())) {
                                /* bg rect is not a normal child */
                                continue;
                        }
-                       (*i)->size_allocate (uniform_size);
-                       for (uint32_t n = 0; n < max_col; ++n) {
-                               col_dimens[n] = uniform_size.width();
-                       }
-                       for (uint32_t n = 0; n < max_row; ++n) {
-                               row_dimens[n] = uniform_size.height();
-                       }
+
+                       CoordsByItem::const_iterator c = coords_by_item.find (*i);
+
+                       Rect r = uniform_cell_size;
+                       r.x1 *= c->second.col_span;
+                       r.y1 *= c->second.row_span;
+
+                       (*i)->size_allocate (r);
                }
+
        } else {
                for (std::list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
 
-                       if (*i == bg) {
+                       if (*i == bg || (collapse_on_hide && !(*i)->visible())) {
                                /* bg rect is not a normal child */
                                continue;
                        }
@@ -256,29 +268,29 @@ Grid::reposition_children ()
 
                        CoordsByItem::const_iterator c = coords_by_item.find (*i);
 
-                       row_dimens[c->second.y] = max (row_dimens[c->second.y], bb.height());
-                       col_dimens[c->second.x] = max (col_dimens[c->second.x]  , bb.width());
-               }
-       }
-
-       /* now sum the row and column widths, so that row_dimens is transformed
-        * into the y coordinate of the upper left of each row, and col_dimens
-        * is transformed into the x coordinate of the left edge of each
-        * column.
-        */
+                       const double per_col_width = bb.width() / c->second.col_span;
+                       const double per_row_height = bb.height() / c->second.row_span;
 
-       double current_top_edge = top_margin + top_padding;
+                       /* set the width of each column spanned by this item
+                        */
 
-       for (uint32_t n = 0; n < max_row; ++n) {
-               if (row_dimens[n]) {
-                       /* height defined for this row */
-                       const double h = row_dimens[n]; /* save height */
-                       row_dimens[n] = current_top_edge;
-                       cerr << "row[" << n << "] @ " << row_dimens[n] << endl;
-                       current_top_edge = current_top_edge + h + row_spacing;
+                       for (int n = 0; n < (int) c->second.col_span; ++n) {
+                               col_dimens[c->second.x + n] = max (col_dimens[c->second.x + n], per_col_width);
+                       }
+                       for (int n = 0; n < (int) c->second.row_span; ++n) {
+                               row_dimens[c->second.y + n] = max (row_dimens[c->second.y + n], per_row_height);
+                       }
                }
        }
 
+       /* now progressively sum the row and column widths, once we're done:
+        *
+        * col_dimens: transformed into the x coordinate of the left edge of each column.
+        *
+        * row_dimens: transformed into the y coordinate of the upper left of each row,
+        *
+        */
+
        double current_right_edge = left_margin + left_padding;
 
        for (uint32_t n = 0; n < max_col; ++n) {
@@ -286,11 +298,21 @@ Grid::reposition_children ()
                        /* a width was defined for this column */
                        const double w = col_dimens[n]; /* save width of this column */
                        col_dimens[n] = current_right_edge;
-                       cerr << "col[" << n << "] @ " << col_dimens[n] << endl;
                        current_right_edge = current_right_edge + w + col_spacing;
                }
        }
 
+       double current_top_edge = top_margin + top_padding;
+
+       for (uint32_t n = 0; n < max_row; ++n) {
+               if (row_dimens[n]) {
+                       /* height defined for this row */
+                       const double h = row_dimens[n]; /* save height */
+                       row_dimens[n] = current_top_edge;
+                       current_top_edge = current_top_edge + h + row_spacing;
+               }
+       }
+
        /* position each item at the upper left of its (row, col) coordinate,
         * given the width of all rows or columns before it.
         */
@@ -302,10 +324,11 @@ Grid::reposition_children ()
                        continue;
                }
 
+               /* do this even for hidden items - it will be corrected when
+                * they become visible again.
+                */
+
                (*i)->set_position (Duple (col_dimens[c->second.x], row_dimens[c->second.y]));
-               cerr << "place " << (*i)->whatami() << " @ " << c->second.x << ", " << c->second.y << " at "
-                    << Duple (col_dimens[c->second.x], row_dimens[c->second.y])
-                    << endl;
        }
 
        _bounding_box_dirty = true;
@@ -315,8 +338,17 @@ Grid::reposition_children ()
 void
 Grid::place (Item* i, double x, double y, double col_span, double row_span)
 {
+       ChildInfo ci;
+
        add (i);
-       coords_by_item.insert (std::make_pair (i, Duple (x, y)));
+
+       ci.item = i;
+       ci.x = x;
+       ci.y = y;
+       ci.col_span = max (1.0, col_span);
+       ci.row_span = max (1.0, row_span);
+
+       coords_by_item.insert (std::make_pair (i, ci));
        reposition_children ();
 }