summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/views/frame/browser_view.cc5
-rw-r--r--chrome/browser/views/options/options_group_view.cc11
-rw-r--r--views/controls/button/checkbox.cc1
-rw-r--r--views/controls/button/image_button.cc2
-rw-r--r--views/controls/button/native_button.cc3
-rw-r--r--views/controls/button/text_button.cc1
-rw-r--r--views/controls/combobox/combobox.cc1
-rw-r--r--views/controls/image_view.cc2
-rw-r--r--views/controls/label.cc11
-rw-r--r--views/controls/tabbed_pane/tabbed_pane.cc3
-rw-r--r--views/controls/textfield/textfield.cc3
-rw-r--r--views/controls/throbber.cc1
-rw-r--r--views/view.cc27
-rw-r--r--views/view.h12
14 files changed, 69 insertions, 14 deletions
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 774eb73..7b019bb 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -420,7 +420,7 @@ BrowserView::BrowserView(Browser* browser)
devtools_container_(NULL),
contents_split_(NULL),
initialized_(false),
- ignore_layout_(false),
+ ignore_layout_(true),
#if defined(OS_WIN)
hung_window_detector_(&hung_plugin_action_),
ticker_(0),
@@ -1859,6 +1859,9 @@ void BrowserView::Init() {
#endif
browser_extender_.reset(new BrowserExtender());
+
+ // We're now initialized and ready to process Layout requests.
+ ignore_layout_ = false;
}
#if defined(OS_WIN)
diff --git a/chrome/browser/views/options/options_group_view.cc b/chrome/browser/views/options/options_group_view.cc
index 39cb18e2..1e742b4 100644
--- a/chrome/browser/views/options/options_group_view.cc
+++ b/chrome/browser/views/options/options_group_view.cc
@@ -119,17 +119,12 @@ void OptionsGroupView::Init() {
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, two_column_layout_id);
- // We need to do this so that the label can calculate an appropriate
- // preferred size (width * height) based on this width constraint. Otherwise
- // Label::GetPreferredSize will return 0,0 as the preferred size.
- title_label_->SetBounds(0, 0, left_column_width, 0);
- layout->AddView(title_label_);
+ layout->AddView(title_label_, 1, 1, GridLayout::FILL, GridLayout::LEADING);
layout->AddView(contents_, 1, 3, GridLayout::FILL, GridLayout::FILL);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(1, two_column_layout_id);
- // See comment above for title_label_.
- description_label_->SetBounds(0, 0, left_column_width, 0);
- layout->AddView(description_label_);
+ layout->AddView(description_label_, 1, 1,
+ GridLayout::FILL, GridLayout::LEADING);
layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
if (show_separator_) {
diff --git a/views/controls/button/checkbox.cc b/views/controls/button/checkbox.cc
index 967d5eb..0899e58 100644
--- a/views/controls/button/checkbox.cc
+++ b/views/controls/button/checkbox.cc
@@ -35,6 +35,7 @@ Checkbox::~Checkbox() {
void Checkbox::SetMultiLine(bool multiline) {
label_->SetMultiLine(multiline);
+ PreferredSizeChanged();
}
void Checkbox::SetChecked(bool checked) {
diff --git a/views/controls/button/image_button.cc b/views/controls/button/image_button.cc
index c9de83f..362b7abe 100644
--- a/views/controls/button/image_button.cc
+++ b/views/controls/button/image_button.cc
@@ -32,6 +32,7 @@ ImageButton::~ImageButton() {
void ImageButton::SetImage(ButtonState aState, const SkBitmap* anImage) {
images_[aState] = anImage ? *anImage : SkBitmap();
+ PreferredSizeChanged();
}
void ImageButton::SetBackground(SkColor color,
@@ -154,6 +155,7 @@ void ToggleImageButton::SetImage(ButtonState state, const SkBitmap* image) {
if (state_ == state)
SchedulePaint();
}
+ PreferredSizeChanged();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/button/native_button.cc b/views/controls/button/native_button.cc
index 5ff98e8..402244c 100644
--- a/views/controls/button/native_button.cc
+++ b/views/controls/button/native_button.cc
@@ -82,6 +82,7 @@ void NativeButton::SetLabel(const std::wstring& label) {
// Update the accessible name whenever the label changes.
SetAccessibleName(label);
+ PreferredSizeChanged();
}
void NativeButton::SetIsDefault(bool is_default) {
@@ -98,12 +99,14 @@ void NativeButton::SetNeedElevation(bool need_elevation) {
need_elevation_ = need_elevation;
if (native_wrapper_)
native_wrapper_->UpdateLabel();
+ PreferredSizeChanged();
}
void NativeButton::SetAppearsAsDefault(bool appears_as_default) {
is_default_ = appears_as_default;
if (native_wrapper_)
native_wrapper_->UpdateDefault();
+ PreferredSizeChanged();
}
void NativeButton::ButtonPressed() {
diff --git a/views/controls/button/text_button.cc b/views/controls/button/text_button.cc
index 158314c..16dae01 100644
--- a/views/controls/button/text_button.cc
+++ b/views/controls/button/text_button.cc
@@ -386,6 +386,7 @@ void TextButton::UpdateTextSize() {
max_text_size_.SetSize(std::max(max_text_size_.width(), text_size_.width()),
std::max(max_text_size_.height(),
text_size_.height()));
+ PreferredSizeChanged();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/views/controls/combobox/combobox.cc b/views/controls/combobox/combobox.cc
index 594dbf3..e213bdc 100644
--- a/views/controls/combobox/combobox.cc
+++ b/views/controls/combobox/combobox.cc
@@ -33,6 +33,7 @@ void Combobox::ModelChanged() {
selected_item_ = std::min(0, model_->GetItemCount());
if (native_wrapper_)
native_wrapper_->UpdateFromModel();
+ PreferredSizeChanged();
}
void Combobox::SetSelectedItem(int index) {
diff --git a/views/controls/image_view.cc b/views/controls/image_view.cc
index bf6219b..4ef4ba0 100644
--- a/views/controls/image_view.cc
+++ b/views/controls/image_view.cc
@@ -21,6 +21,7 @@ ImageView::~ImageView() {
void ImageView::SetImage(const SkBitmap& bm) {
image_ = bm;
+ PreferredSizeChanged();
SchedulePaint();
}
@@ -40,6 +41,7 @@ const SkBitmap& ImageView::GetImage() {
void ImageView::SetImageSize(const gfx::Size& image_size) {
image_size_set_ = true;
image_size_ = image_size;
+ PreferredSizeChanged();
}
bool ImageView::GetImageSize(gfx::Size* image_size) {
diff --git a/views/controls/label.cc b/views/controls/label.cc
index c842191..e2f5091 100644
--- a/views/controls/label.cc
+++ b/views/controls/label.cc
@@ -97,6 +97,7 @@ void Label::PaintBackground(gfx::Canvas* canvas) {
void Label::SetFont(const gfx::Font& font) {
font_ = font;
text_size_valid_ = false;
+ PreferredSizeChanged();
SchedulePaint();
}
@@ -105,6 +106,7 @@ void Label::SetText(const std::wstring& text) {
url_set_ = false;
text_size_valid_ = false;
SetAccessibleName(text);
+ PreferredSizeChanged();
SchedulePaint();
}
@@ -117,6 +119,7 @@ void Label::SetURL(const GURL& url) {
text_ = UTF8ToWide(url_.spec());
url_set_ = true;
text_size_valid_ = false;
+ PreferredSizeChanged();
SchedulePaint();
}
@@ -142,6 +145,7 @@ void Label::SetMultiLine(bool multi_line) {
if (multi_line != is_multi_line_) {
is_multi_line_ = multi_line;
text_size_valid_ = false;
+ PreferredSizeChanged();
SchedulePaint();
}
}
@@ -150,6 +154,7 @@ void Label::SetAllowCharacterBreak(bool allow_character_break) {
if (allow_character_break != allow_character_break_) {
allow_character_break_ = allow_character_break;
text_size_valid_ = false;
+ PreferredSizeChanged();
SchedulePaint();
}
}
@@ -159,6 +164,7 @@ void Label::SetElideInMiddle(bool elide_in_middle) {
if (elide_in_middle != elide_in_middle_) {
elide_in_middle_ = elide_in_middle;
text_size_valid_ = false;
+ PreferredSizeChanged();
SchedulePaint();
}
}
@@ -256,7 +262,10 @@ bool Label::GetAccessibleState(AccessibilityTypes::State* state) {
void Label::SetHasFocusBorder(bool has_focus_border) {
has_focus_border_ = has_focus_border;
- text_size_valid_ &= !is_multi_line_;
+ if (is_multi_line_) {
+ text_size_valid_ = false;
+ PreferredSizeChanged();
+ }
}
void Label::PaintText(gfx::Canvas* canvas,
diff --git a/views/controls/tabbed_pane/tabbed_pane.cc b/views/controls/tabbed_pane/tabbed_pane.cc
index 0207840..7bff98f 100644
--- a/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/views/controls/tabbed_pane/tabbed_pane.cc
@@ -27,6 +27,7 @@ void TabbedPane::SetListener(Listener* listener) {
void TabbedPane::AddTab(const std::wstring& title, View* contents) {
native_tabbed_pane_->AddTab(title, contents);
+ PreferredSizeChanged();
}
void TabbedPane::AddTabAtIndex(int index,
@@ -36,6 +37,7 @@ void TabbedPane::AddTabAtIndex(int index,
native_tabbed_pane_->AddTabAtIndex(index, title, contents,
select_if_first_tab);
contents->SetAccessibleName(title);
+ PreferredSizeChanged();
}
int TabbedPane::GetSelectedTabIndex() {
@@ -48,6 +50,7 @@ View* TabbedPane::GetSelectedTab() {
View* TabbedPane::RemoveTabAtIndex(int index) {
return native_tabbed_pane_->RemoveTabAtIndex(index);
+ PreferredSizeChanged();
}
void TabbedPane::SelectTabAt(int index) {
diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc
index cf54251..c98fcc6 100644
--- a/views/controls/textfield/textfield.cc
+++ b/views/controls/textfield/textfield.cc
@@ -163,16 +163,19 @@ void Textfield::SetFont(const gfx::Font& font) {
font_ = font;
if (native_wrapper_)
native_wrapper_->UpdateFont();
+ PreferredSizeChanged();
}
void Textfield::SetHorizontalMargins(int left, int right) {
if (native_wrapper_)
native_wrapper_->SetHorizontalMargins(left, right);
+ PreferredSizeChanged();
}
void Textfield::SetHeightInLines(int num_lines) {
DCHECK(IsMultiLine());
num_lines_ = num_lines;
+ PreferredSizeChanged();
}
void Textfield::RemoveBorder() {
diff --git a/views/controls/throbber.cc b/views/controls/throbber.cc
index 112f43b..ee49d06 100644
--- a/views/controls/throbber.cc
+++ b/views/controls/throbber.cc
@@ -57,6 +57,7 @@ void Throbber::SetFrames(SkBitmap* frames) {
DCHECK(frames_->width() > 0 && frames_->height() > 0);
DCHECK(frames_->width() % frames_->height() == 0);
frame_count_ = frames_->width() / frames_->height();
+ PreferredSizeChanged();
}
void Throbber::Run() {
diff --git a/views/view.cc b/views/view.cc
index 69cf67f..4ae7bef 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -56,6 +56,7 @@ View::View()
focusable_(false),
accessibility_focusable_(false),
bounds_(0, 0, 0, 0),
+ needs_layout_(true),
parent_(NULL),
is_visible_(true),
is_parent_owned_(true),
@@ -165,6 +166,7 @@ void View::SizeToPreferredSize() {
}
void View::PreferredSizeChanged() {
+ InvalidateLayout();
if (parent_)
parent_->ChildPreferredSizeChanged(this);
}
@@ -181,6 +183,7 @@ int View::GetHeightForWidth(int w) {
void View::DidChangeBounds(const gfx::Rect& previous,
const gfx::Rect& current) {
+ needs_layout_ = false;
Layout();
}
@@ -203,20 +206,37 @@ void View::ScrollRectToVisible(const gfx::Rect& rect) {
/////////////////////////////////////////////////////////////////////////////
void View::Layout() {
+ needs_layout_ = false;
+
// If we have a layout manager, let it handle the layout for us.
if (layout_manager_.get()) {
layout_manager_->Layout(this);
SchedulePaint();
- return;
}
- // Otherwise, just pass on to the child views.
+ // Make sure to propagate the Layout() call to any children that haven't
+ // received it yet through the layout manager and need to be laid out. This
+ // is needed for the case when the child requires a layout but its bounds
+ // weren't changed by the layout manager. If there is no layout manager, we
+ // just propagate the Layout() call down the hierarchy, so whoever receives
+ // the call can take appropriate action.
for (int i = 0, count = GetChildViewCount(); i < count; ++i) {
View* child = GetChildViewAt(i);
- child->Layout();
+ if (child->needs_layout_ || !layout_manager_.get()) {
+ child->needs_layout_ = false;
+ child->Layout();
+ }
}
}
+void View::InvalidateLayout() {
+ if (needs_layout_)
+ return;
+ needs_layout_ = true;
+ if (parent_)
+ parent_->InvalidateLayout();
+}
+
LayoutManager* View::GetLayoutManager() const {
return layout_manager_.get();
}
@@ -705,6 +725,7 @@ void View::ViewHierarchyChangedImpl(bool register_accelerators,
}
ViewHierarchyChanged(is_add, parent, child);
+ parent->needs_layout_ = true;
}
void View::PropagateVisibilityNotifications(View* start, bool is_visible) {
diff --git a/views/view.h b/views/view.h
index 3ac8349..d06d2fa6 100644
--- a/views/view.h
+++ b/views/view.h
@@ -282,6 +282,11 @@ class View : public AcceleratorTarget {
// specific to the current Layout Manager)
virtual void Layout();
+ // Mark this view and all parents to require a relayout. This ensures the
+ // next call to Layout() will propagate to this view, even if the bounds of
+ // parent views do not change.
+ void InvalidateLayout();
+
// Gets/Sets the Layout Manager used by this view to size and place its
// children.
// The LayoutManager is owned by the View and is deleted when the view is
@@ -1041,7 +1046,9 @@ class View : public AcceleratorTarget {
// parent an opportunity to do a fresh layout if that makes sense.
virtual void ChildPreferredSizeChanged(View* child) {}
- // Simply calls ChildPreferredSizeChanged on the parent if there is one.
+ // Invalidates the layout and calls ChildPreferredSizeChanged on the parent
+ // if there is one. Be sure to call View::PreferredSizeChanged when
+ // overriding such that the layout is properly invalidated.
virtual void PreferredSizeChanged();
// Views must invoke this when the tooltip text they are to display changes.
@@ -1222,6 +1229,9 @@ class View : public AcceleratorTarget {
// This View's bounds in the parent coordinate system.
gfx::Rect bounds_;
+ // Whether the view needs to be laid out.
+ bool needs_layout_;
+
// This view's parent
View* parent_;