15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/insets.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/window/dialog_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayoutElement ------------------------------------------------------
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A LayoutElement has a size and location along one axis. It contains
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// methods that are used along both axis.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LayoutElement {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invokes ResetSize on all the layout elements.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void ResetSizes(std::vector<T*>* elements) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reset the layout width of each column.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (typename std::vector<T*>::iterator i = elements->begin();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != elements->end(); ++i) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*i)->ResetSize();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the location of each element to be the sum of the sizes of the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preceding elements.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CalculateLocationsFromSize(std::vector<T*>* elements) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reset the layout width of each column.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int location = 0;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (typename std::vector<T*>::iterator i = elements->begin();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != elements->end(); ++i) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*i)->SetLocation(location);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      location += (*i)->Size();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Distributes delta among the resizable elements.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Each resizable element is given ResizePercent / total_percent * delta
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pixels extra of space.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DistributeDelta(int delta, std::vector<T*>* elements) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delta == 0)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float total_percent = 0;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int resize_count = 0;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (typename std::vector<T*>::iterator i = elements->begin();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != elements->end(); ++i) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      total_percent += (*i)->ResizePercent();
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if ((*i)->ResizePercent() > 0)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        resize_count++;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (total_percent == 0) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // None of the elements are resizable, return.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int remaining = delta;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int resized = resize_count;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (typename std::vector<T*>::iterator i = elements->begin();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != elements->end(); ++i) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      T* element = *i;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (element->ResizePercent() > 0) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int to_give;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (--resized == 0) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          to_give = remaining;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          to_give = static_cast<int>(delta *
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    (element->resize_percent_ / total_percent));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          remaining -= to_give;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        element->SetSize(element->Size() + to_give);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the sum of the size of the elements from start to start + length.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int TotalSize(int start, int length, std::vector<T*>* elements) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(start >= 0 && length > 0 &&
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           start + length <= static_cast<int>(elements->size()));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size = 0;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = start, max = start + length; i < max; ++i) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size += (*elements)[i]->Size();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit LayoutElement(float resize_percent)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : resize_percent_(resize_percent) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(resize_percent >= 0);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LayoutElement() {}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetLocation(int location) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location_ = location;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Location() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return location_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adjusts the size of this LayoutElement to be the max of the current size
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the specified size.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AdjustSize(int size) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ = std::max(size_, size);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resets the size to the initial size. This sets the size to 0, but
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // subclasses that have a different initial size should override.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ResetSize() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSize(0);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetSize(int size) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ = size;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Size() {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetResizePercent(float percent) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resize_percent_ = percent;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float ResizePercent() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return resize_percent_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsResizable() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return resize_percent_ > 0;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float resize_percent_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int location_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LayoutElement);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Column -------------------------------------------------------------
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As the name implies, this represents a Column. Column contains default
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values for views originating in this column.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Column : public LayoutElement {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Column(GridLayout::Alignment h_align,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         GridLayout::Alignment v_align,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         float resize_percent,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         GridLayout::SizeType size_type,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         int fixed_width,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         int min_width,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bool is_padding)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : LayoutElement(resize_percent),
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      h_align_(h_align),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v_align_(v_align),
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_type_(size_type),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      same_size_column_(-1),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fixed_width_(fixed_width),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      min_width_(min_width),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_padding_(is_padding),
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      master_column_(NULL) {}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~Column() {}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GridLayout::Alignment h_align() { return h_align_; }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GridLayout::Alignment v_align() { return v_align_; }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ResetSize() OVERRIDE;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ColumnSet;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class GridLayout;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Column* GetLastMasterColumn();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determines the max size of all linked columns, and sets each column
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to that size. This should only be used for the master column.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnifySameSizedColumnSizes();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AdjustSize(int size) OVERRIDE;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GridLayout::Alignment h_align_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GridLayout::Alignment v_align_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GridLayout::SizeType size_type_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int same_size_column_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fixed_width_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int min_width_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool is_padding_;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If multiple columns have their sizes linked, one is the
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // master column. The master column is identified by the
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // master_column field being equal to itself. The master columns
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same_size_columns field contains the set of Columns with the
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the same size. Columns who are linked to other columns, but
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are not the master column have their master_column pointing to
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one of the other linked columns. Use the method GetLastMasterColumn
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to resolve the true master column.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<Column*> same_size_columns_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Column* master_column_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Column);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Column::ResetSize() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_type_ == GridLayout::FIXED) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSize(fixed_width_);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSize(min_width_);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Column* Column::GetLastMasterColumn() {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (master_column_ == NULL) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (master_column_ == this) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return this;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return master_column_->GetLastMasterColumn();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Column::UnifySameSizedColumnSizes() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(master_column_ == this);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accumulate the size first.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size = 0;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = same_size_columns_.begin();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != same_size_columns_.end(); ++i) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size = std::max(size, (*i)->Size());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then apply it.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = same_size_columns_.begin();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != same_size_columns_.end(); ++i) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*i)->SetSize(size);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Column::AdjustSize(int size) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_type_ == GridLayout::USE_PREF)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayoutElement::AdjustSize(size);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Row -------------------------------------------------------------
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Row : public LayoutElement {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Row(int height, float resize_percent, ColumnSet* column_set)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : LayoutElement(resize_percent),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height_(height),
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      column_set_(column_set),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_ascent_(0),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_descent_(0) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~Row() {}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ResetSize() OVERRIDE {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_ascent_ = max_descent_ = 0;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSize(height_);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* column_set() {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return column_set_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adjusts the size to accomodate the specified ascent/descent.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AdjustSizeForBaseline(int ascent, int descent) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_ascent_ = std::max(ascent, max_ascent_);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_descent_ = std::max(descent, max_descent_);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AdjustSize(max_ascent_ + max_descent_);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_ascent() const {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return max_ascent_;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_descent() const {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return max_descent_;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int height_;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The column set used for this row; null for padding rows.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* column_set_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_ascent_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_descent_;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Row);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ViewState -------------------------------------------------------------
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Identifies the location in the grid of a particular view, along with
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// placement information and size information.
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ViewState {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewState(ColumnSet* column_set, View* view, int start_col, int start_row,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int col_span, int row_span, GridLayout::Alignment h_align,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GridLayout::Alignment v_align, int pref_width, int pref_height)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : column_set(column_set),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view(view),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        start_col(start_col),
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        start_row(start_row),
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        col_span(col_span),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        row_span(row_span),
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        h_align(h_align),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        v_align(v_align),
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pref_width_fixed(pref_width > 0),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pref_height_fixed(pref_height > 0),
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pref_width(pref_width),
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pref_height(pref_height),
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        remaining_width(0),
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        remaining_height(0),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        baseline(-1) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(view && start_col >= 0 && start_row >= 0 && col_span > 0 &&
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           row_span > 0 && start_col < column_set->num_columns() &&
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (start_col + col_span) <= column_set->num_columns());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* const column_set;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* const view;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int start_col;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int start_row;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int col_span;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int row_span;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GridLayout::Alignment h_align;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GridLayout::Alignment v_align;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If true, the pref_width/pref_height were explicitly set and the view's
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferred size is ignored.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool pref_width_fixed;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool pref_height_fixed;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The preferred width/height. These are reset during the layout process.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pref_width;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pref_height;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used during layout. Gives how much width/height has not yet been
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // distributed to the columns/rows the view is in.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int remaining_width;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int remaining_height;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The baseline. Only used if the view is vertically aligned along the
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // baseline.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int baseline;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool CompareByColumnSpan(const ViewState* v1, const ViewState* v2) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return v1->col_span < v2->col_span;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool CompareByRowSpan(const ViewState* v1, const ViewState* v2) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return v1->row_span < v2->row_span;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ColumnSet -------------------------------------------------------------
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColumnSet::ColumnSet(int id) : id_(id) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColumnSet::~ColumnSet() {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&columns_);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::AddPaddingColumn(float resize_percent, int width) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddColumn(GridLayout::FILL, GridLayout::FILL, resize_percent,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GridLayout::FIXED, width, width, true);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::AddColumn(GridLayout::Alignment h_align,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          GridLayout::Alignment v_align,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          float resize_percent,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          GridLayout::SizeType size_type,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int fixed_width,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int min_width) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddColumn(h_align, v_align, resize_percent, size_type, fixed_width,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            min_width, false);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::LinkColumnSizes(int first, ...) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list marker;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(marker, first);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(first >= 0 && first < num_columns());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int last = first, next = va_arg(marker, int); next != -1;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       next = va_arg(marker, int)) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(next >= 0 && next < num_columns());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    columns_[last]->same_size_column_ = next;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last = next;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(marker);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::AddColumn(GridLayout::Alignment h_align,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          GridLayout::Alignment v_align,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          float resize_percent,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          GridLayout::SizeType size_type,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int fixed_width,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int min_width,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bool is_padding) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Column* column = new Column(h_align, v_align, resize_percent, size_type,
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              fixed_width, min_width, is_padding);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(column);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::AddViewState(ViewState* view_state) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // view_states are ordered by column_span (in ascending order).
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<ViewState*>::iterator i = std::lower_bound(view_states_.begin(),
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         view_states_.end(),
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         view_state,
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         CompareByColumnSpan);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_states_.insert(i, view_state);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::CalculateMasterColumns() {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = columns_.begin();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != columns_.end(); ++i) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Column* column = *i;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int same_size_column_index = column->same_size_column_;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (same_size_column_index != -1) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(same_size_column_index >= 0 &&
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             same_size_column_index < static_cast<int>(columns_.size()));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Column* master_column = column->master_column_;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Column* same_size_column = columns_[same_size_column_index];
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Column* same_size_column_master = same_size_column->master_column_;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (master_column == NULL) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Current column is not linked to any other column.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (same_size_column_master == NULL) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Both columns are not linked.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          column->master_column_ = column;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          same_size_column->master_column_ = column;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          column->same_size_columns_.push_back(same_size_column);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          column->same_size_columns_.push_back(column);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Column to link to is linked with other columns.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Add current column to list of linked columns in other columns
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // master column.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          same_size_column->GetLastMasterColumn()->
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              same_size_columns_.push_back(column);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // And update the master column for the current column to that
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // of the same sized column.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          column->master_column_ = same_size_column;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Current column is already linked with another column.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (same_size_column_master == NULL) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Column to link with is not linked to any other columns.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Update it's master_column.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          same_size_column->master_column_ = column;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Add linked column to list of linked column.
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          column->GetLastMasterColumn()->same_size_columns_.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              push_back(same_size_column);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (column->GetLastMasterColumn() !=
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   same_size_column->GetLastMasterColumn()) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // The two columns are already linked with other columns.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::vector<Column*>* same_size_columns =
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &(column->GetLastMasterColumn()->same_size_columns_);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::vector<Column*>* other_same_size_columns =
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &(same_size_column->GetLastMasterColumn()->same_size_columns_);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Add all the columns from the others master to current columns
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // master.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          same_size_columns->insert(same_size_columns->end(),
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     other_same_size_columns->begin(),
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     other_same_size_columns->end());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // The other master is no longer a master, clear its vector of
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // linked columns, and reset its master_column.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          other_same_size_columns->clear();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          same_size_column->GetLastMasterColumn()->master_column_ = column;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AccumulateMasterColumns();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::AccumulateMasterColumns() {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(master_columns_.empty());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = columns_.begin();
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != columns_.end(); ++i) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Column* column = *i;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Column* master_column = column->GetLastMasterColumn();
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (master_column &&
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        std::find(master_columns_.begin(), master_columns_.end(),
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  master_column) == master_columns_.end()) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      master_columns_.push_back(master_column);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point, GetLastMasterColumn may not == master_column
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (may have to go through a few Columns)_. Reset master_column to
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // avoid hops.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    column->master_column_ = master_column;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::UnifySameSizedColumnSizes() {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = master_columns_.begin();
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != master_columns_.end(); ++i) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->UnifySameSizedColumnSizes();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::UpdateRemainingWidth(ViewState* view_state) {
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (int i = view_state->start_col,
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       max_col = view_state->start_col + view_state->col_span;
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       i < max_col; ++i) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_width -= columns_[i]->Size();
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::DistributeRemainingWidth(ViewState* view_state) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is nearly the same as that for rows, but differs in so far as how
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rows and Columns are treated. Rows have two states, resizable or not.
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Columns have three, resizable, USE_PREF or not resizable. This results
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in slightly different handling for distributing unaccounted size.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = view_state->remaining_width;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (width <= 0) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The columns this view is in are big enough to accommodate it.
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determine which columns are resizable, and which have a size type
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of USE_PREF.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resizable_columns = 0;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pref_size_columns = 0;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int start_col = view_state->start_col;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_col = view_state->start_col + view_state->col_span;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float total_resize = 0;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = start_col; i < max_col; ++i) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (columns_[i]->IsResizable()) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      total_resize += columns_[i]->ResizePercent();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resizable_columns++;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (columns_[i]->size_type_ == GridLayout::USE_PREF) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref_size_columns++;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resizable_columns > 0) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There are resizable columns, give them the remaining width. The extra
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // width is distributed using the resize values of each column.
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int remaining_width = width;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = start_col, resize_i = 0; i < max_col; ++i) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (columns_[i]->IsResizable()) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resize_i++;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int delta = (resize_i == resizable_columns) ? remaining_width :
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<int>(width * columns_[i]->ResizePercent() /
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             total_resize);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        remaining_width -= delta;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        columns_[i]->SetSize(columns_[i]->Size() + delta);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (pref_size_columns > 0) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // None of the columns are resizable, distribute the width among those
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that use the preferred size.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int to_distribute = width / pref_size_columns;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = start_col; i < max_col; ++i) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (columns_[i]->size_type_ == GridLayout::USE_PREF) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        width -= to_distribute;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (width < to_distribute)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          to_distribute += width;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        columns_[i]->SetSize(columns_[i]->Size() + to_distribute);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ColumnSet::LayoutWidth() {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = 0;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<Column*>::iterator i = columns_.begin();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != columns_.end(); ++i) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width += (*i)->Size();
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return width;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ColumnSet::GetColumnWidth(int start_col, int col_span) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LayoutElement::TotalSize(start_col, col_span, &columns_);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::ResetColumnXCoordinates() {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayoutElement::CalculateLocationsFromSize(&columns_);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::CalculateSize() {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size pref;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the preferred and remaining sizes.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ViewState*>::iterator i = view_states_.begin();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != view_states_.end(); ++i) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *i;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!view_state->pref_width_fixed || !view_state->pref_height_fixed) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pref = view_state->view->GetPreferredSize();
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!view_state->pref_width_fixed)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_state->pref_width = pref.width();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!view_state->pref_height_fixed)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_state->pref_height = pref.height();
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_width = pref.width();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_height = pref.height();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let layout element reset the sizes for us.
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayoutElement::ResetSizes(&columns_);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Distribute the size of each view with a col span == 1.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ViewState*>::iterator view_state_iterator =
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_states_.begin();
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; view_state_iterator != view_states_.end() &&
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (*view_state_iterator)->col_span == 1; ++view_state_iterator) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *view_state_iterator;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Column* column = columns_[view_state->start_col];
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    column->AdjustSize(view_state->pref_width);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_width -= column->Size();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure all linked columns have the same size.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnifySameSizedColumnSizes();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Distribute the size of each view with a column span > 1.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; view_state_iterator != view_states_.end(); ++view_state_iterator) {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *view_state_iterator;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the remaining_width from columns this view_state touches.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateRemainingWidth(view_state);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Distribute the remaining width.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DistributeRemainingWidth(view_state);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the size of linked columns.
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This may need to be combined with previous step.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UnifySameSizedColumnSizes();
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColumnSet::Resize(int delta) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayoutElement::DistributeDelta(delta, &columns_);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GridLayout -------------------------------------------------------------
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GridLayout::GridLayout(View* host)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : host_(host),
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      calculated_master_columns_(false),
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      remaining_row_span_(0),
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_row_(-1),
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_column_(0),
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_row_col_set_(NULL),
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      adding_view_(false) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GridLayout::~GridLayout() {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&column_sets_);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&view_states_);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&rows_);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GridLayout* GridLayout::CreatePanel(View* host) {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GridLayout* layout = new GridLayout(host);
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  layout->SetInsets(kPanelVertMargin, kButtonHEdgeMarginNew,
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    kPanelVertMargin, kButtonHEdgeMarginNew);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return layout;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::SetInsets(int top, int left, int bottom, int right) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  insets_.Set(top, left, bottom, right);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::SetInsets(const gfx::Insets& insets) {
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  insets_ = insets;
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColumnSet* GridLayout::AddColumnSet(int id) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(GetColumnSet(id) == NULL);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* column_set = new ColumnSet(id);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_sets_.push_back(column_set);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return column_set;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColumnSet* GridLayout::GetColumnSet(int id) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ColumnSet*>::iterator i = column_sets_.begin();
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != column_sets_.end(); ++i) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*i)->id_ == id) {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return *i;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::StartRowWithPadding(float vertical_resize, int column_set_id,
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     float padding_resize, int padding) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddPaddingRow(padding_resize, padding);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartRow(vertical_resize, column_set_id);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::StartRow(float vertical_resize, int column_set_id) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* column_set = GetColumnSet(column_set_id);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(column_set);
7120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AddRow(new Row(0, vertical_resize, column_set));
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddPaddingRow(float vertical_resize, int pixel_count) {
7160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AddRow(new Row(pixel_count, vertical_resize, NULL));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::SkipColumns(int col_count) {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(col_count > 0);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_column_ += col_count;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_row_col_set_ &&
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         next_column_ <= current_row_col_set_->num_columns());
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkipPaddingColumns();
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddView(View* view) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddView(view, 1, 1);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddView(View* view, int col_span, int row_span) {
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_row_col_set_ &&
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         next_column_ < current_row_col_set_->num_columns());
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Column* column = current_row_col_set_->columns_[next_column_];
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddView(view, col_span, row_span, column->h_align(), column->v_align());
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddView(View* view, int col_span, int row_span,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         Alignment h_align, Alignment v_align) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddView(view, col_span, row_span, h_align, v_align, 0, 0);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddView(View* view, int col_span, int row_span,
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         Alignment h_align, Alignment v_align,
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int pref_width, int pref_height) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_row_col_set_ && col_span > 0 && row_span > 0 &&
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (next_column_ + col_span) <= current_row_col_set_->num_columns());
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't support baseline alignment of views spanning rows. Please add if
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // you need it.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(v_align != BASELINE || row_span == 1);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewState* state =
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ViewState(current_row_col_set_, view, next_column_, current_row_,
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    col_span, row_span, h_align, v_align, pref_width,
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    pref_height);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddViewState(state);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CalculateSize(int pref_size, GridLayout::Alignment alignment,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int* location, int* size) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (alignment != GridLayout::FILL) {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int available_size = *size;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = std::min(*size, pref_size);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (alignment) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case GridLayout::LEADING:
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Nothing to do, location already points to start.
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case GridLayout::BASELINE:  // If we were asked to align on baseline, but
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  // the view doesn't have a baseline, fall back
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  // to center.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case GridLayout::CENTER:
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *location += (available_size - *size) / 2;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case GridLayout::TRAILING:
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *location = *location + available_size - *size;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::Installed(View* host) {
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::Uninstalled(View* host) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::ViewAdded(View* host, View* view) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host && adding_view_);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::ViewRemoved(View* host, View* view) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::Layout(View* host) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SizeRowsAndColumns sets the size and location of each row/column, but
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not of the views.
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size pref;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SizeRowsAndColumns(true, host_->width(), host_->height(), &pref);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size each view.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ViewState*>::iterator i = view_states_.begin();
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != view_states_.end(); ++i) {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *i;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ColumnSet* column_set = view_state->column_set;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* view = (*i)->view;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(view);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int x = column_set->columns_[view_state->start_col]->Location() +
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            insets_.left();
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int width = column_set->GetColumnWidth(view_state->start_col,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           view_state->col_span);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CalculateSize(view_state->pref_width, view_state->h_align,
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &x, &width);
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int y = rows_[view_state->start_row]->Location() + insets_.top();
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int height = LayoutElement::TotalSize(view_state->start_row,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          view_state->row_span, &rows_);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view_state->v_align == BASELINE && view_state->baseline != -1) {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y += rows_[view_state->start_row]->max_ascent() - view_state->baseline;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height = view_state->pref_height;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CalculateSize(view_state->pref_height, view_state->v_align, &y, &height);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view->SetBounds(x, y, width, height);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size GridLayout::GetPreferredSize(const View* host) const {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size out;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SizeRowsAndColumns(false, 0, 0, &out);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.SetSize(std::max(out.width(), minimum_size_.width()),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              std::max(out.height(), minimum_size_.height()));
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int GridLayout::GetPreferredHeightForWidth(const View* host, int width) const {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_ == host);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size pref;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SizeRowsAndColumns(false, width, 0, &pref);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pref.height();
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::SizeRowsAndColumns(bool layout, int width, int height,
848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    gfx::Size* pref) const {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the master columns have been calculated.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CalculateMasterColumnsIfNecessary();
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref->SetSize(0, 0);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rows_.empty())
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate the preferred width of each of the columns. Some views'
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferred heights are derived from their width, as such we need to
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calculate the size of the columns first.
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ColumnSet*>::iterator i = column_sets_.begin();
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != column_sets_.end(); ++i) {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->CalculateSize();
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref->set_width(std::max(pref->width(), (*i)->LayoutWidth()));
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref->set_width(pref->width() + insets_.width());
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go over the columns again and set them all to the size we settled for.
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width = width ? width : pref->width();
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ColumnSet*>::iterator i = column_sets_.begin();
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != column_sets_.end(); ++i) {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're doing a layout, divy up any extra space.
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*i)->Resize(width - (*i)->LayoutWidth() - insets_.left() -
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 insets_.right());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // And reset the x coordinates.
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->ResetColumnXCoordinates();
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the height of each row.
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayoutElement::ResetSizes(&rows_);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do the following:
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // . If the view is aligned along it's baseline, obtain the baseline from the
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   view and update the rows ascent/descent.
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // . Reset the remaining_height of each view state.
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // . If the width the view will be given is different than it's pref, ask
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   for the height given a particularly width.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ViewState*>::iterator i= view_states_.begin();
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != view_states_.end() ; ++i) {
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *i;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_height = view_state->pref_height;
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view_state->v_align == BASELINE)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_state->baseline = view_state->view->GetBaseline();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view_state->h_align == FILL) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The view is resizable. As the pref height may vary with the width,
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ask for the pref again.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int actual_width =
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          view_state->column_set->GetColumnWidth(view_state->start_col,
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 view_state->col_span);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (actual_width != view_state->pref_width &&
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !view_state->pref_height_fixed) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // The width this view will get differs from its preferred. Some Views
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // pref height varies with its width; ask for the preferred again.
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_state->pref_height =
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            view_state->view->GetHeightForWidth(actual_width);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_state->remaining_height = view_state->pref_height;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the height/ascent/descent of each row from the views.
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ViewState*>::iterator view_states_iterator = view_states_.begin();
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; view_states_iterator != view_states_.end() &&
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*view_states_iterator)->row_span == 1; ++view_states_iterator) {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *view_states_iterator;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Row* row = rows_[view_state->start_row];
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->AdjustSize(view_state->remaining_height);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view_state->baseline != -1 &&
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_state->baseline <= view_state->pref_height) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      row->AdjustSizeForBaseline(view_state->baseline,
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          view_state->pref_height - view_state->baseline);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_height = 0;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Distribute the height of each view with a row span > 1.
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; view_states_iterator != view_states_.end(); ++view_states_iterator) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ViewState* view_state = *view_states_iterator;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the remaining_width from columns this view_state touches.
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateRemainingHeightFromRows(view_state);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Distribute the remaining height.
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DistributeRemainingHeight(view_state);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the location of each of the rows.
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayoutElement::CalculateLocationsFromSize(&rows_);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now know the preferred height, set it here.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref->set_height(rows_[rows_.size() - 1]->Location() +
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rows_[rows_.size() - 1]->Size() + insets_.height());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (layout && height != pref->height()) {
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're doing a layout, and the height differs from the preferred height,
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // divy up the extra space.
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayoutElement::DistributeDelta(height - pref->height(), &rows_);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reset y locations.
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayoutElement::CalculateLocationsFromSize(&rows_);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GridLayout::CalculateMasterColumnsIfNecessary() const {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!calculated_master_columns_) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    calculated_master_columns_ = true;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::vector<ColumnSet*>::iterator i = column_sets_.begin();
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != column_sets_.end(); ++i) {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*i)->CalculateMasterColumns();
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddViewState(ViewState* view_state) {
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(view_state->view && (view_state->view->parent() == NULL ||
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              view_state->view->parent() == host_));
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!view_state->view->parent()) {
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adding_view_ = true;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AddChildView(view_state->view);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adding_view_ = false;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remaining_row_span_ = std::max(remaining_row_span_, view_state->row_span);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_column_ += view_state->col_span;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_row_col_set_->AddViewState(view_state);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // view_states are ordered by row_span (in ascending order).
9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<ViewState*>::iterator i = std::lower_bound(view_states_.begin(),
9765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         view_states_.end(),
9775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         view_state,
9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         CompareByRowSpan);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_states_.insert(i, view_state);
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkipPaddingColumns();
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::AddRow(Row* row) {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_row_++;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remaining_row_span_--;
98658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // GridLayout requires that if you add a View with a row span you use the same
98758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // column set for each of the rows the view lands it. This DCHECK verifies
98858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // that.
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(remaining_row_span_ <= 0 ||
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         row->column_set() == NULL ||
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         row->column_set() == GetLastValidColumnSet());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_column_ = 0;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rows_.push_back(row);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_row_col_set_ = row->column_set();
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkipPaddingColumns();
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GridLayout::UpdateRemainingHeightFromRows(ViewState* view_state) const {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0, start_row = view_state->start_row;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i < view_state->row_span; ++i) {
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_height -= rows_[i + start_row]->Size();
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GridLayout::DistributeRemainingHeight(ViewState* view_state) const {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = view_state->remaining_height;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height <= 0)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determine the number of resizable rows the view touches.
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resizable_rows = 0;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int start_row = view_state->start_row;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_row = view_state->start_row + view_state->row_span;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = start_row; i < max_row; ++i) {
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rows_[i]->IsResizable()) {
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resizable_rows++;
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resizable_rows > 0) {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There are resizable rows, give the remaining height to them.
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int to_distribute = height / resizable_rows;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = start_row; i < max_row; ++i) {
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rows_[i]->IsResizable()) {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        height -= to_distribute;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (height < to_distribute) {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Give all slop to the last column.
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          to_distribute += height;
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rows_[i]->SetSize(rows_[i]->Size() + to_distribute);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // None of the rows are resizable, divy the remaining height up equally
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // among all rows the view touches.
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int each_row_height = height / view_state->row_span;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = start_row; i < max_row; ++i) {
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height -= each_row_height;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (height < each_row_height)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        each_row_height += height;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rows_[i]->SetSize(rows_[i]->Size() + each_row_height);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_state->remaining_height = 0;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GridLayout::SkipPaddingColumns() {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!current_row_col_set_)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (next_column_ < current_row_col_set_->num_columns() &&
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         current_row_col_set_->columns_[next_column_]->is_padding_) {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_column_++;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColumnSet* GridLayout::GetLastValidColumnSet() {
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = current_row_ - 1; i >= 0; --i) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rows_[i]->column_set())
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return rows_[i]->column_set();
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
1065