void GridLayout::SizeRowsAndColumns(bool layout, int width, int height, gfx::Size* pref) { // Make sure the master columns have been calculated. CalculateMasterColumnsIfNecessary(); pref->SetSize(0, 0); if(rows_.empty()) { return; } // Calculate the preferred width of each of the columns. Some views' // preferred heights are derived from their width, as such we need to // calculate the size of the columns first. for(std::vector<ColumnSet*>::iterator i=column_sets_.begin(); i!=column_sets_.end(); ++i) { (*i)->CalculateSize(); pref->set_width(std::max(pref->width(), (*i)->LayoutWidth())); } pref->set_width(pref->width() + left_inset_ + right_inset_); // Go over the columns again and set them all to the size we settled for. width = width ? width : pref->width(); for(std::vector<ColumnSet*>::iterator i=column_sets_.begin(); i!=column_sets_.end(); ++i) { // We're doing a layout, divy up any extra space. (*i)->Resize(width - (*i)->LayoutWidth() - left_inset_ - right_inset_); // And reset the x coordinates. (*i)->ResetColumnXCoordinates(); } // Reset the height of each row. LayoutElement::ResetSizes(&rows_); // Do the following: // . If the view is aligned along it's baseline, obtain the baseline from the // view and update the rows ascent/descent. // . Reset the remaining_height of each view state. // . If the width the view will be given is different than it's pref, ask // for the height given a particularly width. for(std::vector<ViewState*>::iterator i=view_states_.begin(); i!=view_states_.end(); ++i) { ViewState* view_state = *i; view_state->remaining_height = view_state->pref_height; if(view_state->v_align == BASELINE) { view_state->baseline = view_state->view->GetBaseline(); } if(view_state->h_align == FILL) { // The view is resizable. As the pref height may vary with the width, // ask for the pref again. int actual_width = view_state->column_set->GetColumnWidth( view_state->start_col, view_state->col_span); if(actual_width!=view_state->pref_width && !view_state->pref_height_fixed) { // The width this view will get differs from it's preferred. Some Views // pref height varies with it's width; ask for the preferred again. view_state->pref_height = view_state->view->GetHeightForWidth(actual_width); view_state->remaining_height = view_state->pref_height; } } } // Update the height/ascent/descent of each row from the views. std::vector<ViewState*>::iterator view_states_iterator = view_states_.begin(); for(; view_states_iterator!=view_states_.end() && (*view_states_iterator)->row_span==1; ++view_states_iterator) { ViewState* view_state = *view_states_iterator; Row* row = rows_[view_state->start_row]; row->AdjustSize(view_state->remaining_height); if(view_state->baseline!=-1 && view_state->baseline<=view_state->pref_height) { row->AdjustSizeForBaseline(view_state->baseline, view_state->pref_height - view_state->baseline); } view_state->remaining_height = 0; } // Distribute the height of each view with a row span > 1. for(; view_states_iterator!=view_states_.end(); ++view_states_iterator) { ViewState* view_state = *view_states_iterator; // Update the remaining_width from columns this view_state touches. UpdateRemainingHeightFromRows(view_state); // Distribute the remaining height. DistributeRemainingHeight(view_state); } // Update the location of each of the rows. LayoutElement::CalculateLocationsFromSize(&rows_); // We now know the preferred height, set it here. pref->set_height(rows_[rows_.size()-1]->Location() + rows_[rows_.size()-1]->Size() + top_inset_ + bottom_inset_); if(layout && height!=pref->height()) { // We're doing a layout, and the height differs from the preferred height, // divy up the extra space. LayoutElement::DistributeDelta(height-pref->height(), &rows_); // Reset y locations. LayoutElement::CalculateLocationsFromSize(&rows_); } }