| Index: ui/views/anchor_attribute.cc | 
| diff --git a/ui/views/anchor_attribute.cc b/ui/views/anchor_attribute.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..685700f680228b5c1069f3d29cac03b17b10bc18 | 
| --- /dev/null | 
| +++ b/ui/views/anchor_attribute.cc | 
| @@ -0,0 +1,119 @@ | 
| +// Copyright (c) 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "ui/views/anchor_attribute.h" | 
| + | 
| +namespace views { | 
| + | 
| +AnchorContent::AnchorContent() | 
| +    : attribute_(nullptr), | 
| +      anchors_({Anchor::Top, Anchor::Left}), | 
| +      anchor_basis_(0, 0), | 
| +      last_parent_size_(0, 0) {} | 
| + | 
| +AnchorContent::AnchorContent(Anchors anchors) | 
| +    : attribute_(nullptr), | 
| +      anchors_(anchors), | 
| +      anchor_basis_(0, 0), | 
| +      last_parent_size_(0, 0) {} | 
| + | 
| +AnchorContent::AnchorContent(const AnchorContent& content) | 
| +    : attribute_(content.attribute_), | 
| +      anchors_(content.anchors_), | 
| +      anchor_basis_(content.anchor_basis_), | 
| +      last_parent_size_(content.last_parent_size_) {} | 
| + | 
| +AnchorAttribute::AnchorAttribute() : | 
| +  CustomAttribute<AnchorContent>(AnchorContent()) { | 
| +  GetContent().SetAttribute(this); | 
| +} | 
| + | 
| +AnchorAttribute::AnchorAttribute(Anchors anchors) : | 
| +  CustomAttribute<AnchorContent>(AnchorContent(anchors)) { | 
| +  GetContent().SetAttribute(this); | 
| +} | 
| + | 
| +AnchorAttribute::AnchorAttribute(AnchorContent& content) : | 
| +  CustomAttribute<AnchorContent>(content) { | 
| +  GetContent().SetAttribute(this); | 
| +} | 
| + | 
| +AttributeId AnchorAttribute::Identity() const { | 
| +  return GetAttributeId<AnchorAttribute>(); | 
| +} | 
| + | 
| +void AnchorAttribute::Notification(Attribute::NotifyType type, | 
| +                                   Attribute* attribute) { | 
| +  FillAttribute* fill = attribute->AsAttribute<FillAttribute>(); | 
| +  if (fill) { | 
| +    if (type == Attribute::NotifyType::AttributeAdded) | 
| +      GetContent().SetAnchors(AnchorContent::AnchorFill(fill->fill())); | 
| +    else | 
| +      GetContent().SetAnchors(Anchors({Anchor::Left, Anchor::Top})); | 
| +  } | 
| +} | 
| + | 
| +void AnchorAttribute::ViewNotification(View* view) { | 
| +  GetContent().UpdateAnchorBasis(view); | 
| +} | 
| + | 
| +Anchors AnchorContent::AnchorFill(Fill fill) { | 
| +  static int anchor_fill[] = { | 
| +    // Fill::Left | 
| +    (1 << static_cast<int>(Anchor::Left)) | | 
| +    (1 << static_cast<int>(Anchor::Top)) | | 
| +    (1 << static_cast<int>(Anchor::Bottom)), | 
| +    // Fill::Top | 
| +    (1 << static_cast<int>(Anchor::Left)) | | 
| +    (1 << static_cast<int>(Anchor::Top)) | | 
| +    (1 << static_cast<int>(Anchor::Right)), | 
| +    // Fill::Right | 
| +    (1 << static_cast<int>(Anchor::Top)) | | 
| +    (1 << static_cast<int>(Anchor::Right)) | | 
| +    (1 << static_cast<int>(Anchor::Bottom)), | 
| +    // Fill::Bottom | 
| +    (1 << static_cast<int>(Anchor::Left)) | | 
| +    (1 << static_cast<int>(Anchor::Right)) | | 
| +    (1 << static_cast<int>(Anchor::Bottom)), | 
| +    // Fill::Content | 
| +    (1 << static_cast<int>(Anchor::Left)) | | 
| +    (1 << static_cast<int>(Anchor::Top)) | | 
| +    (1 << static_cast<int>(Anchor::Right)) | | 
| +    (1 << static_cast<int>(Anchor::Bottom)), | 
| +  }; | 
| +  return Anchors(anchor_fill[static_cast<int>(fill)]); | 
| +} | 
| + | 
| +void AnchorContent::SetAnchors(Anchors anchors) { | 
| +  if (anchors_ != anchors) { | 
| +    anchors_ = anchors; | 
| +    UpdateAnchorBasis(attribute_->view()); | 
| +  } | 
| +} | 
| + | 
| +void AnchorContent::UpdateAnchorBasis(View* view) { | 
| +  if (anchors_.Equals({Anchor::Left, Anchor::Top})) { | 
| +    last_parent_size_ = gfx::Size(0, 0); | 
| +    return; | 
| +  } | 
| +  gfx::Point center_point = view->bounds().CenterPoint(); | 
| +  if (anchors_.Contains(Anchor::Right)) | 
| +    if (anchors_.Contains(Anchor::Left)) | 
| +      anchor_basis_.set_x(view->width()); | 
| +    else | 
| +      anchor_basis_.set_x(view->x()); | 
| +  else | 
| +    anchor_basis_.set_x(center_point.x()); | 
| +  if (anchors_.Contains(Anchor::Bottom)) | 
| +    if (anchors_.Contains(Anchor::Top)) | 
| +      anchor_basis_.set_y(view->height()); | 
| +    else | 
| +      anchor_basis_.set_y(view->y()); | 
| +  else | 
| +    anchor_basis_.set_y(center_point.y()); | 
| +  if (view->parent()) | 
| +    last_parent_size_ = view->parent()->GetContentsBounds().size(); | 
| +} | 
| + | 
| +}  // namespace views | 
|  |