Commit c45a003e authored by Peter Boström's avatar Peter Boström Committed by Commit Bot

Add fixed-width support to BubbleDialogDelegate

This enables removing overrides to CalculatePreferredSize() that try to
return a fixed size to fit within a specific dialog width.

It also fixes infinite recursion in such overrides where there's no
LayoutManager and GetHeightForWidth() defaults to calling
GetPreferredSize(), which calls the CalculatePreferredSize() override
that calls GetHeightForWidth().

Bug: 1128500
Change-Id: I75508e790cd6d7fdc31a40b5dad96366ddf8545c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2466141
Commit-Queue: Peter Boström <pbos@chromium.org>
Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816403}
parent 125ffef6
...@@ -185,8 +185,6 @@ class InternalPageInfoBubbleView : public PageInfoBubbleViewBase { ...@@ -185,8 +185,6 @@ class InternalPageInfoBubbleView : public PageInfoBubbleViewBase {
const GURL& url); const GURL& url);
~InternalPageInfoBubbleView() override; ~InternalPageInfoBubbleView() override;
gfx::Size CalculatePreferredSize() const override;
DISALLOW_COPY_AND_ASSIGN(InternalPageInfoBubbleView); DISALLOW_COPY_AND_ASSIGN(InternalPageInfoBubbleView);
}; };
...@@ -398,6 +396,9 @@ InternalPageInfoBubbleView::InternalPageInfoBubbleView( ...@@ -398,6 +396,9 @@ InternalPageInfoBubbleView::InternalPageInfoBubbleView(
ChromeLayoutProvider::Get()->GetInsetsMetric(views::INSETS_DIALOG)); ChromeLayoutProvider::Get()->GetInsetsMetric(views::INSETS_DIALOG));
set_margins(gfx::Insets()); set_margins(gfx::Insets());
SetFixedWidth(ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_BUBBLE_PREFERRED_WIDTH));
SetTitle(text); SetTitle(text);
views::BubbleDialogDelegateView::CreateBubble(this); views::BubbleDialogDelegateView::CreateBubble(this);
...@@ -419,20 +420,6 @@ InternalPageInfoBubbleView::InternalPageInfoBubbleView( ...@@ -419,20 +420,6 @@ InternalPageInfoBubbleView::InternalPageInfoBubbleView(
InternalPageInfoBubbleView::~InternalPageInfoBubbleView() {} InternalPageInfoBubbleView::~InternalPageInfoBubbleView() {}
gfx::Size InternalPageInfoBubbleView::CalculatePreferredSize() const {
// Without a layout manager this will recurse infinitely
// (GetHeightForWidth() calls CalculatePreferredSize()).
// TODO(crbug.com/1128500): Fix infinite recursion or always
// install a layout manager.
if (!GetLayoutManager())
return gfx::Size();
const int width = ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_BUBBLE_PREFERRED_WIDTH) -
margins().width();
return gfx::Size(width, GetHeightForWidth(width));
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// PageInfoBubbleView // PageInfoBubbleView
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -408,6 +408,11 @@ ClientView* BubbleDialogDelegate::CreateClientView(Widget* widget) { ...@@ -408,6 +408,11 @@ ClientView* BubbleDialogDelegate::CreateClientView(Widget* widget) {
client_view_->layer()->SetIsFastRoundedCorner(true); client_view_->layer()->SetIsFastRoundedCorner(true);
} }
if (fixed_width_) {
// TODO(pbos): Make sure this reacts to or NOTREACHED()s changes to margins.
client_view_->set_fixed_width(fixed_width_ - margins().width());
}
return client_view_; return client_view_;
} }
...@@ -528,6 +533,12 @@ void BubbleDialogDelegate::SetHighlightedButton(Button* highlighted_button) { ...@@ -528,6 +533,12 @@ void BubbleDialogDelegate::SetHighlightedButton(Button* highlighted_button) {
UpdateHighlightedButton(true); UpdateHighlightedButton(true);
} }
void BubbleDialogDelegate::SetFixedWidth(int width) {
// SetFixedWidth should be called before |client_view_| is created.
DCHECK(!client_view_);
fixed_width_ = width;
}
void BubbleDialogDelegate::SetArrow(BubbleBorder::Arrow arrow) { void BubbleDialogDelegate::SetArrow(BubbleBorder::Arrow arrow) {
SetArrowWithoutResizing(arrow); SetArrowWithoutResizing(arrow);
// If SetArrow() is called before CreateWidget(), there's no need to update // If SetArrow() is called before CreateWidget(), there's no need to update
......
...@@ -174,6 +174,10 @@ class VIEWS_EXPORT BubbleDialogDelegate : public DialogDelegate, ...@@ -174,6 +174,10 @@ class VIEWS_EXPORT BubbleDialogDelegate : public DialogDelegate,
// view. // view.
void SetHighlightedButton(Button* highlighted_button); void SetHighlightedButton(Button* highlighted_button);
// Set a fixed width for the dialog. The client view will size itself to
// preferred height for this width, minus dialog margins.
void SetFixedWidth(int width);
// The bubble's parent window - this can only be usefully set before creating // The bubble's parent window - this can only be usefully set before creating
// the bubble's widget. If there is one, the bubble will be stacked above it, // the bubble's widget. If there is one, the bubble will be stacked above it,
// and it will become the Views parent window for the bubble. // and it will become the Views parent window for the bubble.
...@@ -335,6 +339,9 @@ class VIEWS_EXPORT BubbleDialogDelegate : public DialogDelegate, ...@@ -335,6 +339,9 @@ class VIEWS_EXPORT BubbleDialogDelegate : public DialogDelegate,
bool focus_traversable_from_anchor_view_ = true; bool focus_traversable_from_anchor_view_ = true;
ViewTracker highlighted_button_tracker_; ViewTracker highlighted_button_tracker_;
// Use a fixed dialog width instead of the |client_view_| preferred size.
int fixed_width_ = 0;
// Insets applied to the |anchor_view_| bounds. // Insets applied to the |anchor_view_| bounds.
gfx::Insets anchor_view_insets_; gfx::Insets anchor_view_insets_;
......
...@@ -140,6 +140,10 @@ BubbleDialogModelHost::BubbleDialogModelHost( ...@@ -140,6 +140,10 @@ BubbleDialogModelHost::BubbleDialogModelHost(
set_close_on_deactivate(model_->close_on_deactivate(GetPassKey())); set_close_on_deactivate(model_->close_on_deactivate(GetPassKey()));
SetFixedWidth(LayoutProvider::Get()->GetDistanceMetric(
anchor_view ? views::DISTANCE_BUBBLE_PREFERRED_WIDTH
: views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
AddInitialFields(); AddInitialFields();
} }
...@@ -186,15 +190,6 @@ void BubbleDialogModelHost::OnDialogInitialized() { ...@@ -186,15 +190,6 @@ void BubbleDialogModelHost::OnDialogInitialized() {
} }
} }
gfx::Size BubbleDialogModelHost::CalculatePreferredSize() const {
const int width = LayoutProvider::Get()->GetDistanceMetric(
GetModalType() == ui::MODAL_TYPE_NONE
? views::DISTANCE_BUBBLE_PREFERRED_WIDTH
: views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH) -
margins().width();
return gfx::Size(width, GetHeightForWidth(width));
}
void BubbleDialogModelHost::Close() { void BubbleDialogModelHost::Close() {
DCHECK(model_); DCHECK(model_);
DCHECK(GetWidget()); DCHECK(GetWidget());
......
...@@ -46,7 +46,6 @@ class VIEWS_EXPORT BubbleDialogModelHost : public BubbleDialogDelegateView, ...@@ -46,7 +46,6 @@ class VIEWS_EXPORT BubbleDialogModelHost : public BubbleDialogDelegateView,
// GetInitiallyFocusedView(). // GetInitiallyFocusedView().
View* GetInitiallyFocusedView() override; View* GetInitiallyFocusedView() override;
void OnDialogInitialized() override; void OnDialogInitialized() override;
gfx::Size CalculatePreferredSize() const override;
// ui::DialogModelHost: // ui::DialogModelHost:
void Close() override; void Close() override;
......
...@@ -40,7 +40,15 @@ void ClientView::WidgetClosing() {} ...@@ -40,7 +40,15 @@ void ClientView::WidgetClosing() {}
gfx::Size ClientView::CalculatePreferredSize() const { gfx::Size ClientView::CalculatePreferredSize() const {
// |contents_view_| is allowed to be NULL up until the point where this view // |contents_view_| is allowed to be NULL up until the point where this view
// is attached to a Container. // is attached to a Container.
return contents_view_ ? contents_view_->GetPreferredSize() : gfx::Size(); if (!contents_view_)
return gfx::Size();
if (fixed_width_) {
return gfx::Size(fixed_width_,
contents_view_->GetHeightForWidth(fixed_width_));
}
return contents_view_->GetPreferredSize();
} }
gfx::Size ClientView::GetMaximumSize() const { gfx::Size ClientView::GetMaximumSize() const {
......
...@@ -30,6 +30,8 @@ class VIEWS_EXPORT ClientView : public View { ...@@ -30,6 +30,8 @@ class VIEWS_EXPORT ClientView : public View {
ClientView(Widget* widget, View* contents_view); ClientView(Widget* widget, View* contents_view);
~ClientView() override = default; ~ClientView() override = default;
void set_fixed_width(int width) { fixed_width_ = width; }
// Returned value signals whether the Widget can be closed. Specialized // Returned value signals whether the Widget can be closed. Specialized
// ClientView subclasses can override this default behavior to allow the // ClientView subclasses can override this default behavior to allow the
// close to be blocked until the user corrects mistakes, accepts a warning // close to be blocked until the user corrects mistakes, accepts a warning
...@@ -71,6 +73,8 @@ class VIEWS_EXPORT ClientView : public View { ...@@ -71,6 +73,8 @@ class VIEWS_EXPORT ClientView : public View {
private: private:
// The View that this ClientView contains. // The View that this ClientView contains.
View* contents_view_; View* contents_view_;
int fixed_width_ = 0;
}; };
} // namespace views } // namespace views
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment