X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fgrid.cc;h=e46a184e42ce19dd3a5d6e4be29da8a849a36960;hb=ae0dcdc0c5d13483271065c360e378202d20170a;hp=323cdbf1ad9ee2bba89ad1cb4bf999bddae7ad23;hpb=14cb9ec795ba524275dfeb8bf0f9f0582523bb66;p=ardour.git diff --git a/libs/canvas/grid.cc b/libs/canvas/grid.cc index 323cdbf1ad..e46a184e42 100644 --- a/libs/canvas/grid.cc +++ b/libs/canvas/grid.cc @@ -30,38 +30,44 @@ using std::endl; Grid::Grid (Canvas* canvas) : Item (canvas) - , spacing (0) + , row_spacing (0) + , col_spacing (0) , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0) , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0) , homogenous (false) { - self = new Rectangle (this); - self->set_outline (false); - self->set_fill (false); + bg = new Rectangle (this); + bg->set_outline (false); + bg->set_fill (false); + bg->hide (); } Grid::Grid (Item* parent) : Item (parent) - , spacing (0) + , row_spacing (0) + , col_spacing (0) , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0) , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0) , homogenous (false) { - self = new Rectangle (this); - self->set_outline (false); - self->set_fill (false); + bg = new Rectangle (this); + bg->set_outline (false); + bg->set_fill (false); + bg->hide (); } Grid::Grid (Item* parent, Duple const & p) : Item (parent, p) - , spacing (0) + , row_spacing (0) + , col_spacing (0) , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0) , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0) , homogenous (true) { - self = new Rectangle (this); - self->set_outline (false); - self->set_fill (false); + bg = new Rectangle (this); + bg->set_outline (false); + bg->set_fill (false); + bg->hide (); } void @@ -91,19 +97,25 @@ Grid::compute_bounding_box () const if (_bounding_box) { Rect r = _bounding_box; - _bounding_box = r.expand (outline_width() + top_margin, - outline_width() + right_margin, - outline_width() + bottom_margin, - outline_width() + left_margin); + _bounding_box = r.expand (outline_width() + top_margin + top_padding, + outline_width() + right_margin + right_padding, + outline_width() + bottom_margin + bottom_padding, + outline_width() + left_margin + left_padding); } _bounding_box_dirty = false; } void -Grid::set_spacing (double s) +Grid::set_row_spacing (double s) { - spacing = s; + row_spacing = s; +} + +void +Grid::set_col_spacing (double s) +{ + col_spacing = s; } void @@ -147,14 +159,14 @@ Grid::set_margin (double t, double r, double b, double l) } void -Grid::reset_self () +Grid::reset_bg () { if (_bounding_box_dirty) { compute_bounding_box (); } if (!_bounding_box) { - self->hide (); + bg->hide (); return; } @@ -162,7 +174,7 @@ Grid::reset_self () /* XXX need to shrink by margin */ - self->set (r); + bg->set (r); } void @@ -172,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 row_dimens; vector 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::iterator i = _items.begin(); i != _items.end(); ++i) { - if (*i == self) { + if (*i == bg || (collapse_on_hide && !(*i)->visible())) { continue; } @@ -208,31 +221,42 @@ 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)); + } + + for (uint32_t n = 0; n < max_col; ++n) { + col_dimens[n] = uniform_cell_size.width(); } - cerr << "Uniform size will be " << uniform_size << endl; + for (uint32_t n = 0; n < max_row; ++n) { + row_dimens[n] = uniform_cell_size.height(); + } for (std::list::iterator i = _items.begin(); i != _items.end(); ++i) { - if (*i == self) { - /* self-rect is not a normal child */ + + 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::iterator i = _items.begin(); i != _items.end(); ++i) { - if (*i == self) { - /* self-rect is not a normal child */ + if (*i == bg || (collapse_on_hide && !(*i)->visible())) { + /* bg rect is not a normal child */ continue; } @@ -244,38 +268,48 @@ 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()); - } - } + const double per_col_width = bb.width() / c->second.col_span; + const double per_row_height = bb.height() / c->second.row_span; - /* 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. - */ + /* set the width of each column spanned by this item + */ - double current_top_edge = top_margin; - - 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 + top_padding + bottom_padding; + 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); + } } } - double current_right_edge = left_margin; + /* 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) { if (col_dimens[n]) { /* 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 + left_padding + right_padding; + 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; } } @@ -290,21 +324,31 @@ 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; - reset_self (); + reset_bg (); } void -Grid::place (Item* i, Duple at) +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, at)); + + 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 (); }