summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc4
-rw-r--r--chrome/browser/ui/views/autofill/card_unmask_prompt_views.h21
-rw-r--r--chrome/browser/ui/views/autofill/save_card_bubble_views.cc4
-rw-r--r--chrome/browser/ui/views/autofill/save_card_bubble_views.h2
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc7
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h4
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc5
-rw-r--r--chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc8
-rw-r--r--chrome/browser/ui/views/extensions/extension_installed_bubble_view.h2
-rw-r--r--chrome/browser/ui/views/session_crashed_bubble_view.cc74
-rw-r--r--chrome/browser/ui/views/session_crashed_bubble_view.h35
-rw-r--r--ui/views/bubble/bubble_delegate.cc2
-rw-r--r--ui/views/bubble/bubble_delegate.h3
-rw-r--r--ui/views/bubble/bubble_dialog_delegate.cc341
-rw-r--r--ui/views/bubble/bubble_dialog_delegate.h215
-rw-r--r--ui/views/bubble/bubble_frame_view.cc35
-rw-r--r--ui/views/bubble/bubble_frame_view.h9
-rw-r--r--ui/views/examples/widget_example.cc7
-rw-r--r--ui/views/views.gyp2
-rw-r--r--ui/views/window/dialog_client_view.cc54
-rw-r--r--ui/views/window/dialog_client_view.h20
-rw-r--r--ui/views/window/dialog_client_view_unittest.cc52
-rw-r--r--ui/views/window/dialog_delegate.cc10
-rw-r--r--ui/views/window/dialog_delegate.h5
24 files changed, 655 insertions, 266 deletions
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
index e1f951f8..3e78123 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -288,10 +288,6 @@ void CardUnmaskPromptViews::DeleteDelegate() {
delete this;
}
-int CardUnmaskPromptViews::GetDialogButtons() const {
- return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
-}
-
base::string16 CardUnmaskPromptViews::GetDialogButtonLabel(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_OK)
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
index a677b1212..d6a206d 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.h
@@ -34,11 +34,11 @@ namespace autofill {
class DecoratedTextfield;
class CardUnmaskPromptViews : public CardUnmaskPromptView,
- views::ComboboxListener,
- views::DialogDelegateView,
- views::TextfieldController,
- views::LinkListener,
- gfx::AnimationDelegate {
+ public views::ComboboxListener,
+ public views::DialogDelegateView,
+ public views::TextfieldController,
+ public views::LinkListener,
+ public gfx::AnimationDelegate {
public:
CardUnmaskPromptViews(CardUnmaskPromptController* controller,
content::WebContents* web_contents);
@@ -53,7 +53,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
// views::DialogDelegateView
View* GetContentsView() override;
- views::View* CreateFootnoteView() override;
+ View* CreateFootnoteView() override;
// views::View
gfx::Size GetPreferredSize() const override;
@@ -63,11 +63,10 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
void DeleteDelegate() override;
- int GetDialogButtons() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
bool ShouldDefaultButtonBeBlue() const override;
bool IsDialogButtonEnabled(ui::DialogButton button) const override;
- views::View* GetInitiallyFocusedView() override;
+ View* GetInitiallyFocusedView() override;
bool Cancel() override;
bool Accept() override;
@@ -88,7 +87,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
friend class CardUnmaskPromptViewTesterViews;
// A view that allows changing the opacity of its contents.
- class FadeOutView : public views::View {
+ class FadeOutView : public View {
public:
FadeOutView();
~FadeOutView() override;
@@ -125,7 +124,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
CardUnmaskPromptController* controller_;
content::WebContents* web_contents_;
- views::View* main_contents_;
+ View* main_contents_;
// Expository language at the top of the dialog.
views::Label* instructions_;
@@ -134,7 +133,7 @@ class CardUnmaskPromptViews : public CardUnmaskPromptView,
views::Label* permanent_error_label_;
// Holds the cvc and expiration inputs.
- views::View* input_row_;
+ View* input_row_;
DecoratedTextfield* cvc_input_;
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
index 007c617..10706a8 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -78,12 +78,12 @@ void SaveCardBubbleViews::Hide() {
Close();
}
-scoped_ptr<views::View> SaveCardBubbleViews::CreateFootnoteView() {
+views::View* SaveCardBubbleViews::CreateFootnoteView() {
if (controller_->GetLegalMessageLines().empty())
return nullptr;
// Use BoxLayout to provide insets around the label.
- scoped_ptr<View> view(new View());
+ View* view = new View();
view->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.h b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
index 85c6a3d..34490c4 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.h
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
@@ -45,7 +45,7 @@ class SaveCardBubbleViews : public SaveCardBubbleView,
void Hide() override;
// views::BubbleDelegateView
- scoped_ptr<views::View> CreateFootnoteView() override;
+ views::View* CreateFootnoteView() override;
// views::View
gfx::Size GetPreferredSize() const override;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 6b8de33..81a488b 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -238,16 +238,15 @@ views::View* BookmarkBubbleView::GetInitiallyFocusedView() {
return title_tf_;
}
-scoped_ptr<views::View> BookmarkBubbleView::CreateFootnoteView() {
+views::View* BookmarkBubbleView::CreateFootnoteView() {
if (!SyncPromoUI::ShouldShowSyncPromo(profile_))
return nullptr;
content::RecordAction(
base::UserMetricsAction("Signin_Impression_FromBookmarkBubble"));
- return scoped_ptr<views::View>(
- new BubbleSyncPromoView(delegate_.get(), IDS_BOOKMARK_SYNC_PROMO_LINK,
- IDS_BOOKMARK_SYNC_PROMO_MESSAGE));
+ return new BubbleSyncPromoView(delegate_.get(), IDS_BOOKMARK_SYNC_PROMO_LINK,
+ IDS_BOOKMARK_SYNC_PROMO_MESSAGE);
}
BookmarkBubbleView::BookmarkBubbleView(
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
index c8cd970..580f4d1 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
@@ -71,8 +71,8 @@ class BookmarkBubbleView : public views::BubbleDelegateView,
// views::BubbleDelegateView:
const char* GetClassName() const override;
- views::View* GetInitiallyFocusedView() override;
- scoped_ptr<views::View> CreateFootnoteView() override;
+ View* GetInitiallyFocusedView() override;
+ View* CreateFootnoteView() override;
// Creates a BookmarkBubbleView.
BookmarkBubbleView(views::View* anchor_view,
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
index 523516d..00f2019 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
@@ -87,14 +87,15 @@ TEST_F(BookmarkBubbleViewTest, SyncPromoSignedIn) {
SetUpSigninManager("fake_username");
CreateBubbleView();
bubble_->Init();
- EXPECT_FALSE(bubble_->CreateFootnoteView());
+ scoped_ptr<views::View> footnote(bubble_->CreateFootnoteView());
+ EXPECT_FALSE(footnote);
}
// Verifies that the sync promo is displayed for a user that is not signed in.
TEST_F(BookmarkBubbleViewTest, SyncPromoNotSignedIn) {
CreateBubbleView();
bubble_->Init();
- scoped_ptr<views::View> footnote = bubble_->CreateFootnoteView();
+ scoped_ptr<views::View> footnote(bubble_->CreateFootnoteView());
#if defined(OS_CHROMEOS)
EXPECT_FALSE(footnote);
#else // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
index 7b4d42e..9e86a81 100644
--- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
@@ -176,13 +176,13 @@ void ExtensionInstalledBubbleView::UpdateAnchorView() {
SetAnchorView(reference_view);
}
-scoped_ptr<views::View> ExtensionInstalledBubbleView::CreateFootnoteView() {
+views::View* ExtensionInstalledBubbleView::CreateFootnoteView() {
if (!(bubble_->options() & ExtensionInstalledBubble::SIGN_IN_PROMO))
return nullptr;
- return scoped_ptr<views::View>(
- new BubbleSyncPromoView(this, IDS_EXTENSION_INSTALLED_SYNC_PROMO_LINK_NEW,
- IDS_EXTENSION_INSTALLED_SYNC_PROMO_NEW));
+ return new BubbleSyncPromoView(this,
+ IDS_EXTENSION_INSTALLED_SYNC_PROMO_LINK_NEW,
+ IDS_EXTENSION_INSTALLED_SYNC_PROMO_NEW);
}
void ExtensionInstalledBubbleView::WindowClosing() {
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.h b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.h
index 6d11e07..8eec05b 100644
--- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.h
+++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.h
@@ -50,7 +50,7 @@ class ExtensionInstalledBubbleView : public BubbleSyncPromoDelegate,
private:
// views::BubbleDelegateView:
- scoped_ptr<views::View> CreateFootnoteView() override;
+ View* CreateFootnoteView() override;
void WindowClosing() override;
gfx::Rect GetAnchorRect() const override;
void OnWidgetClosing(views::Widget* widget) override;
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index ccde39b..bd75757 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -46,10 +46,10 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/checkbox.h"
-#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/separator.h"
#include "ui/views/controls/styled_label.h"
+#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
@@ -213,7 +213,7 @@ void SessionCrashedBubbleView::ShowForReal(
SessionCrashedBubbleView* crash_bubble =
new SessionCrashedBubbleView(anchor_view, browser, web_contents,
offer_uma_optin);
- views::BubbleDelegateView::CreateBubble(crash_bubble)->Show();
+ views::BubbleDialogDelegateView::CreateBubble(crash_bubble)->Show();
RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_SHOWN);
if (uma_opted_in_already)
@@ -225,11 +225,10 @@ SessionCrashedBubbleView::SessionCrashedBubbleView(
Browser* browser,
content::WebContents* web_contents,
bool offer_uma_optin)
- : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
+ : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
content::WebContentsObserver(web_contents),
browser_(browser),
web_contents_(web_contents),
- restore_button_(NULL),
uma_option_(NULL),
offer_uma_optin_(offer_uma_optin),
started_navigation_(false),
@@ -247,10 +246,6 @@ SessionCrashedBubbleView::~SessionCrashedBubbleView() {
browser_->tab_strip_model()->RemoveObserver(this);
}
-views::View* SessionCrashedBubbleView::GetInitiallyFocusedView() {
- return restore_button_;
-}
-
base::string16 SessionCrashedBubbleView::GetWindowTitle() const {
return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_BUBBLE_TITLE);
}
@@ -266,10 +261,12 @@ bool SessionCrashedBubbleView::ShouldShowCloseButton() const {
void SessionCrashedBubbleView::OnWidgetDestroying(views::Widget* widget) {
if (!restored_)
RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_IGNORED);
- BubbleDelegateView::OnWidgetDestroying(widget);
+ BubbleDialogDelegateView::OnWidgetDestroying(widget);
}
void SessionCrashedBubbleView::Init() {
+ SetLayoutManager(new views::FillLayout());
+
// Description text label.
views::Label* text_label = new views::Label(
l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_MESSAGE));
@@ -277,37 +274,10 @@ void SessionCrashedBubbleView::Init() {
text_label->SetLineHeight(20);
text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
text_label->SizeToFit(kWidthOfDescriptionText);
-
- // Restore button.
- restore_button_ = new views::LabelButton(
- this, l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON));
- restore_button_->SetStyle(views::Button::STYLE_BUTTON);
- restore_button_->SetIsDefault(true);
-
- GridLayout* layout = new GridLayout(this);
- SetLayoutManager(layout);
-
- // Text row.
- const int kTextColumnSetId = 0;
- views::ColumnSet* cs = layout->AddColumnSet(kTextColumnSetId);
- cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
- GridLayout::FIXED, kWidthOfDescriptionText, 0);
-
- // Restore button row.
- const int kButtonColumnSetId = 1;
- cs = layout->AddColumnSet(kButtonColumnSetId);
- cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
-
- layout->StartRow(0, kTextColumnSetId);
- layout->AddView(text_label);
- layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
-
- layout->StartRow(0, kButtonColumnSetId);
- layout->AddView(restore_button_);
+ AddChildView(text_label);
}
-scoped_ptr<views::View> SessionCrashedBubbleView::CreateFootnoteView() {
+views::View* SessionCrashedBubbleView::CreateFootnoteView() {
if (!offer_uma_optin_)
return nullptr;
@@ -346,8 +316,8 @@ scoped_ptr<views::View> SessionCrashedBubbleView::CreateFootnoteView() {
uma_label->SetBorder(views::Border::CreateEmptyBorder(1, 0, 0, 0));
// Create a view to hold the checkbox and the text.
- scoped_ptr<views::View> uma_view(new views::View());
- GridLayout* uma_layout = new GridLayout(uma_view.get());
+ views::View* uma_view = new views::View();
+ GridLayout* uma_layout = new GridLayout(uma_view);
uma_view->SetLayoutManager(uma_layout);
const int kReportColumnSetId = 0;
@@ -365,10 +335,24 @@ scoped_ptr<views::View> SessionCrashedBubbleView::CreateFootnoteView() {
return uma_view;
}
-void SessionCrashedBubbleView::ButtonPressed(views::Button* sender,
- const ui::Event& event) {
- DCHECK_EQ(sender, restore_button_);
- RestorePreviousSession(sender);
+bool SessionCrashedBubbleView::Accept() {
+ RestorePreviousSession();
+ return true;
+}
+
+bool SessionCrashedBubbleView::Close() {
+ // Don't default to Accept() just because that's the only choice. Instead, do
+ // nothing.
+ return true;
+}
+
+int SessionCrashedBubbleView::GetDialogButtons() const {
+ return ui::DIALOG_BUTTON_OK;
+}
+
+base::string16 SessionCrashedBubbleView::GetDialogButtonLabel(
+ ui::DialogButton button) const {
+ return l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON);
}
void SessionCrashedBubbleView::StyledLabelLinkClicked(views::StyledLabel* label,
@@ -418,7 +402,7 @@ void SessionCrashedBubbleView::TabDetachedAt(content::WebContents* contents,
CloseBubble();
}
-void SessionCrashedBubbleView::RestorePreviousSession(views::Button* sender) {
+void SessionCrashedBubbleView::RestorePreviousSession() {
SessionRestore::RestoreSessionAfterCrash(browser_);
RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_RESTORED);
restored_ = true;
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.h b/chrome/browser/ui/views/session_crashed_bubble_view.h
index 869e92d..012dfd5 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.h
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.h
@@ -12,14 +12,12 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/controls/button/button.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/styled_label_listener.h"
namespace views {
class Checkbox;
class GridLayout;
-class LabelButton;
class Widget;
}
@@ -33,14 +31,12 @@ class Browser;
// It creates a session restore request bubble when the previous session has
// crashed. It also presents an option to enable metrics reporting, if it not
// enabled already.
-class SessionCrashedBubbleView
- : public SessionCrashedBubble,
- public views::BubbleDelegateView,
- public views::ButtonListener,
- public views::StyledLabelListener,
- public content::WebContentsObserver,
- public content::NotificationObserver,
- public TabStripModelObserver {
+class SessionCrashedBubbleView : public SessionCrashedBubble,
+ public views::BubbleDialogDelegateView,
+ public views::StyledLabelListener,
+ public content::WebContentsObserver,
+ public content::NotificationObserver,
+ public TabStripModelObserver {
public:
// A helper class that listens to browser removal event.
class BrowserRemovalObserver;
@@ -59,19 +55,19 @@ class SessionCrashedBubbleView
~SessionCrashedBubbleView() override;
// WidgetDelegateView methods.
- views::View* GetInitiallyFocusedView() override;
base::string16 GetWindowTitle() const override;
bool ShouldShowWindowTitle() const override;
bool ShouldShowCloseButton() const override;
void OnWidgetDestroying(views::Widget* widget) override;
- scoped_ptr<views::View> CreateFootnoteView() override;
+ views::View* CreateFootnoteView() override;
+ bool Accept() override;
+ bool Close() override;
+ int GetDialogButtons() const override;
+ base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
- // views::BubbleDelegateView methods.
+ // views::BubbleDialogDelegateView methods.
void Init() override;
- // views::ButtonListener methods.
- void ButtonPressed(views::Button* sender, const ui::Event& event) override;
-
// views::StyledLabelListener methods.
void StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
@@ -98,7 +94,7 @@ class SessionCrashedBubbleView
void TabDetachedAt(content::WebContents* contents, int index) override;
// Restore previous session after user selects so.
- void RestorePreviousSession(views::Button* sender);
+ void RestorePreviousSession();
// Close and destroy the bubble.
void CloseBubble();
@@ -111,9 +107,6 @@ class SessionCrashedBubbleView
// The web content associated with current bubble.
content::WebContents* web_contents_;
- // Button for the user to confirm a session restore.
- views::LabelButton* restore_button_;
-
// Checkbox for the user to opt-in to UMA reporting.
views::Checkbox* uma_option_;
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc
index a18c088..698c4a4 100644
--- a/ui/views/bubble/bubble_delegate.cc
+++ b/ui/views/bubble/bubble_delegate.cc
@@ -207,7 +207,7 @@ void BubbleDelegateView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,
Widget* widget) const {
}
-scoped_ptr<View> BubbleDelegateView::CreateFootnoteView() {
+View* BubbleDelegateView::CreateFootnoteView() {
return nullptr;
}
diff --git a/ui/views/bubble/bubble_delegate.h b/ui/views/bubble/bubble_delegate.h
index a0e3ccc..9392251 100644
--- a/ui/views/bubble/bubble_delegate.h
+++ b/ui/views/bubble/bubble_delegate.h
@@ -23,6 +23,7 @@ class BubbleFrameView;
// BubbleDelegateView creates frame and client views for bubble Widgets.
// BubbleDelegateView itself is the client's contents view.
+// TODO(estade): remove this in favor of BubbleDialogDelegateView.
class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
public WidgetObserver {
public:
@@ -112,7 +113,7 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
Widget* widget) const;
// Creates and returns a view to be displayed at the bottom of the bubble.
- virtual scoped_ptr<View> CreateFootnoteView();
+ virtual View* CreateFootnoteView();
// Sets |margins_| to a default picked for smaller bubbles.
void UseCompactMargins();
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc
new file mode 100644
index 0000000..a893bcf
--- /dev/null
+++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -0,0 +1,341 @@
+// Copyright 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/bubble/bubble_dialog_delegate.h"
+
+#include "build/build_config.h"
+#include "ui/accessibility/ax_view_state.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/color_utils.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/native_theme/native_theme.h"
+#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/focus/view_storage.h"
+#include "ui/views/layout/layout_constants.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
+#include "ui/views/window/dialog_client_view.h"
+
+#if defined(OS_WIN)
+#include "ui/base/win/shell.h"
+#endif
+
+namespace views {
+
+namespace {
+
+// Create a widget to host the bubble.
+Widget* CreateBubbleWidget(BubbleDialogDelegateView* bubble) {
+ Widget* bubble_widget = new Widget();
+ Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
+ bubble_params.delegate = bubble;
+ bubble_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
+ bubble_params.accept_events = bubble->accept_events();
+ if (bubble->parent_window())
+ bubble_params.parent = bubble->parent_window();
+ else if (bubble->anchor_widget())
+ bubble_params.parent = bubble->anchor_widget()->GetNativeView();
+ bubble_params.activatable = bubble->CanActivate()
+ ? Widget::InitParams::ACTIVATABLE_YES
+ : Widget::InitParams::ACTIVATABLE_NO;
+ bubble->OnBeforeBubbleWidgetInit(&bubble_params, bubble_widget);
+ bubble_widget->Init(bubble_params);
+ if (bubble_params.parent)
+ bubble_widget->StackAbove(bubble_params.parent);
+ return bubble_widget;
+}
+
+} // namespace
+
+// static
+const char BubbleDialogDelegateView::kViewClassName[] =
+ "BubbleDialogDelegateView";
+
+BubbleDialogDelegateView::~BubbleDialogDelegateView() {
+ if (GetWidget())
+ GetWidget()->RemoveObserver(this);
+ SetLayoutManager(NULL);
+ SetAnchorView(NULL);
+}
+
+// static
+Widget* BubbleDialogDelegateView::CreateBubble(
+ BubbleDialogDelegateView* bubble_delegate) {
+ bubble_delegate->Init();
+ // Get the latest anchor widget from the anchor view at bubble creation time.
+ bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView());
+ Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);
+
+#if defined(OS_WIN)
+ // If glass is enabled, the bubble is allowed to extend outside the bounds of
+ // the parent frame and let DWM handle compositing. If not, then we don't
+ // want to allow the bubble to extend the frame because it will be clipped.
+ bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled());
+#elif (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX)
+ // Linux clips bubble windows that extend outside their parent window bounds.
+ // Mac never adjusts.
+ bubble_delegate->set_adjust_if_offscreen(false);
+#endif
+
+ bubble_delegate->SizeToContents();
+ bubble_widget->AddObserver(bubble_delegate);
+ return bubble_widget;
+}
+
+bool BubbleDialogDelegateView::ShouldShowCloseButton() const {
+ return false;
+}
+
+ClientView* BubbleDialogDelegateView::CreateClientView(Widget* widget) {
+ DialogClientView* client = new DialogClientView(widget, GetContentsView());
+ client->set_button_row_insets(gfx::Insets());
+ return client;
+}
+
+NonClientFrameView* BubbleDialogDelegateView::CreateNonClientFrameView(
+ Widget* widget) {
+ BubbleFrameView* frame = new BubbleFrameView(
+ gfx::Insets(kPanelVertMargin, kPanelHorizMargin, 0, kPanelHorizMargin),
+ margins());
+ // Note: In CreateBubble, the call to SizeToContents() will cause
+ // the relayout that this call requires.
+ frame->SetTitleFontList(GetTitleFontList());
+ frame->SetFootnoteView(CreateFootnoteView());
+
+ BubbleBorder::Arrow adjusted_arrow = arrow();
+ if (base::i18n::IsRTL())
+ adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow);
+ frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(
+ new BubbleBorder(adjusted_arrow, shadow(), color())));
+ return frame;
+}
+
+void BubbleDialogDelegateView::GetAccessibleState(ui::AXViewState* state) {
+ state->role = ui::AX_ROLE_DIALOG;
+}
+
+const char* BubbleDialogDelegateView::GetClassName() const {
+ return kViewClassName;
+}
+
+void BubbleDialogDelegateView::OnWidgetClosing(Widget* widget) {
+ DCHECK(GetBubbleFrameView());
+ if (widget == GetWidget() && close_reason_ == CloseReason::UNKNOWN &&
+ GetBubbleFrameView()->close_button_clicked()) {
+ close_reason_ = CloseReason::CLOSE_BUTTON;
+ }
+}
+
+void BubbleDialogDelegateView::OnWidgetDestroying(Widget* widget) {
+ if (anchor_widget() == widget)
+ SetAnchorView(NULL);
+}
+
+void BubbleDialogDelegateView::OnWidgetVisibilityChanging(Widget* widget,
+ bool visible) {
+#if defined(OS_WIN)
+ // On Windows we need to handle this before the bubble is visible or hidden.
+ // Please see the comment on the OnWidgetVisibilityChanging function. On
+ // other platforms it is fine to handle it after the bubble is shown/hidden.
+ HandleVisibilityChanged(widget, visible);
+#endif
+}
+
+void BubbleDialogDelegateView::OnWidgetVisibilityChanged(Widget* widget,
+ bool visible) {
+#if !defined(OS_WIN)
+ HandleVisibilityChanged(widget, visible);
+#endif
+}
+
+void BubbleDialogDelegateView::OnWidgetActivationChanged(Widget* widget,
+ bool active) {
+ if (close_on_deactivate() && widget == GetWidget() && !active) {
+ if (close_reason_ == CloseReason::UNKNOWN)
+ close_reason_ = CloseReason::DEACTIVATION;
+ GetWidget()->Close();
+ }
+}
+
+void BubbleDialogDelegateView::OnWidgetBoundsChanged(
+ Widget* widget,
+ const gfx::Rect& new_bounds) {
+ if (GetBubbleFrameView() && anchor_widget() == widget)
+ SizeToContents();
+}
+
+View* BubbleDialogDelegateView::GetAnchorView() const {
+ return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_);
+}
+
+gfx::Rect BubbleDialogDelegateView::GetAnchorRect() const {
+ if (!GetAnchorView())
+ return anchor_rect_;
+
+ anchor_rect_ = GetAnchorView()->GetBoundsInScreen();
+ anchor_rect_.Inset(anchor_view_insets_);
+ return anchor_rect_;
+}
+
+void BubbleDialogDelegateView::OnBeforeBubbleWidgetInit(
+ Widget::InitParams* params,
+ Widget* widget) const {}
+
+void BubbleDialogDelegateView::UseCompactMargins() {
+ const int kCompactMargin = 6;
+ margins_.Set(kCompactMargin, kCompactMargin, kCompactMargin, kCompactMargin);
+}
+
+void BubbleDialogDelegateView::SetAlignment(
+ BubbleBorder::BubbleAlignment alignment) {
+ GetBubbleFrameView()->bubble_border()->set_alignment(alignment);
+ SizeToContents();
+}
+
+void BubbleDialogDelegateView::SetArrowPaintType(
+ BubbleBorder::ArrowPaintType paint_type) {
+ GetBubbleFrameView()->bubble_border()->set_paint_arrow(paint_type);
+ SizeToContents();
+}
+
+void BubbleDialogDelegateView::OnAnchorBoundsChanged() {
+ SizeToContents();
+}
+
+BubbleDialogDelegateView::BubbleDialogDelegateView()
+ : BubbleDialogDelegateView(nullptr, BubbleBorder::TOP_LEFT) {}
+
+BubbleDialogDelegateView::BubbleDialogDelegateView(View* anchor_view,
+ BubbleBorder::Arrow arrow)
+ : close_on_esc_(true),
+ close_on_deactivate_(true),
+ anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
+ anchor_widget_(NULL),
+ arrow_(arrow),
+ shadow_(BubbleBorder::SMALL_SHADOW),
+ color_explicitly_set_(false),
+ margins_(kPanelVertMargin,
+ kPanelHorizMargin,
+ kPanelVertMargin,
+ kPanelHorizMargin),
+ accept_events_(true),
+ border_accepts_events_(true),
+ adjust_if_offscreen_(true),
+ parent_window_(NULL),
+ close_reason_(CloseReason::UNKNOWN) {
+ if (anchor_view)
+ SetAnchorView(anchor_view);
+ AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
+ UpdateColorsFromTheme(GetNativeTheme());
+}
+
+gfx::Rect BubbleDialogDelegateView::GetBubbleBounds() {
+ // The argument rect has its origin at the bubble's arrow anchor point;
+ // its size is the preferred size of the bubble's client view (this view).
+ bool anchor_minimized = anchor_widget() && anchor_widget()->IsMinimized();
+ return GetBubbleFrameView()->GetUpdatedWindowBounds(
+ GetAnchorRect(), GetWidget()->client_view()->GetPreferredSize(),
+ adjust_if_offscreen_ && !anchor_minimized);
+}
+
+const gfx::FontList& BubbleDialogDelegateView::GetTitleFontList() const {
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ return rb.GetFontList(ui::ResourceBundle::MediumFont);
+}
+
+bool BubbleDialogDelegateView::AcceleratorPressed(
+ const ui::Accelerator& accelerator) {
+ if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
+ return false;
+ close_reason_ = CloseReason::ESCAPE;
+ GetWidget()->Close();
+ return true;
+}
+
+void BubbleDialogDelegateView::OnNativeThemeChanged(
+ const ui::NativeTheme* theme) {
+ UpdateColorsFromTheme(theme);
+}
+
+void BubbleDialogDelegateView::Init() {}
+
+void BubbleDialogDelegateView::SetAnchorView(View* anchor_view) {
+ // When the anchor view gets set the associated anchor widget might
+ // change as well.
+ if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) {
+ if (anchor_widget()) {
+ anchor_widget_->RemoveObserver(this);
+ anchor_widget_ = NULL;
+ }
+ if (anchor_view) {
+ anchor_widget_ = anchor_view->GetWidget();
+ if (anchor_widget_)
+ anchor_widget_->AddObserver(this);
+ }
+ }
+
+ // Remove the old storage item and set the new (if there is one).
+ ViewStorage* view_storage = ViewStorage::GetInstance();
+ if (view_storage->RetrieveView(anchor_view_storage_id_))
+ view_storage->RemoveView(anchor_view_storage_id_);
+ if (anchor_view)
+ view_storage->StoreView(anchor_view_storage_id_, anchor_view);
+
+ // Do not update anchoring for NULL views; this could indicate that our
+ // NativeWindow is being destroyed, so it would be dangerous for us to update
+ // our anchor bounds at that point. (It's safe to skip this, since if we were
+ // to update the bounds when |anchor_view| is NULL, the bubble won't move.)
+ if (anchor_view && GetWidget())
+ OnAnchorBoundsChanged();
+}
+
+void BubbleDialogDelegateView::SetAnchorRect(const gfx::Rect& rect) {
+ anchor_rect_ = rect;
+ if (GetWidget())
+ OnAnchorBoundsChanged();
+}
+
+void BubbleDialogDelegateView::SizeToContents() {
+ GetWidget()->SetBounds(GetBubbleBounds());
+}
+
+BubbleFrameView* BubbleDialogDelegateView::GetBubbleFrameView() const {
+ const NonClientView* view =
+ GetWidget() ? GetWidget()->non_client_view() : NULL;
+ return view ? static_cast<BubbleFrameView*>(view->frame_view()) : NULL;
+}
+
+void BubbleDialogDelegateView::UpdateColorsFromTheme(
+ const ui::NativeTheme* theme) {
+ if (!color_explicitly_set_)
+ color_ = theme->GetSystemColor(ui::NativeTheme::kColorId_BubbleBackground);
+ set_background(Background::CreateSolidBackground(color()));
+ BubbleFrameView* frame_view = GetBubbleFrameView();
+ if (frame_view)
+ frame_view->bubble_border()->set_background_color(color());
+}
+
+void BubbleDialogDelegateView::HandleVisibilityChanged(Widget* widget,
+ bool visible) {
+ if (widget == GetWidget() && anchor_widget() &&
+ anchor_widget()->GetTopLevelWidget()) {
+ if (visible)
+ anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering();
+ else
+ anchor_widget()->GetTopLevelWidget()->EnableInactiveRendering();
+ }
+
+ // Fire AX_EVENT_ALERT for bubbles marked as AX_ROLE_ALERT_DIALOG; this
+ // instructs accessibility tools to read the bubble in its entirety rather
+ // than just its title and initially focused view. See
+ // http://crbug.com/474622 for details.
+ if (widget == GetWidget() && visible) {
+ ui::AXViewState state;
+ GetAccessibleState(&state);
+ if (state.role == ui::AX_ROLE_ALERT_DIALOG)
+ NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+ }
+}
+
+} // namespace views
diff --git a/ui/views/bubble/bubble_dialog_delegate.h b/ui/views/bubble/bubble_dialog_delegate.h
new file mode 100644
index 0000000..fc61adc
--- /dev/null
+++ b/ui/views/bubble/bubble_dialog_delegate.h
@@ -0,0 +1,215 @@
+// Copyright 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.
+
+#ifndef UI_VIEWS_BUBBLE_BUBBLE_DIALOG_DELEGATE_H_
+#define UI_VIEWS_BUBBLE_BUBBLE_DIALOG_DELEGATE_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "ui/views/bubble/bubble_border.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
+#include "ui/views/window/dialog_delegate.h"
+
+namespace gfx {
+class FontList;
+class Rect;
+}
+
+namespace views {
+
+class BubbleFrameView;
+
+// BubbleDialogDelegateView is a special DialogDelegateView for bubbles.
+class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
+ public WidgetObserver {
+ public:
+ // Internal class name.
+ static const char kViewClassName[];
+
+ enum class CloseReason {
+ DEACTIVATION,
+ ESCAPE,
+ CLOSE_BUTTON,
+ UNKNOWN,
+ };
+
+ ~BubbleDialogDelegateView() override;
+
+ // Create and initialize the bubble Widget(s) with proper bounds.
+ static Widget* CreateBubble(BubbleDialogDelegateView* bubble_delegate);
+
+ // WidgetDelegateView overrides:
+ bool ShouldShowCloseButton() const override;
+ ClientView* CreateClientView(Widget* widget) override;
+ NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
+ void GetAccessibleState(ui::AXViewState* state) override;
+ const char* GetClassName() const override;
+
+ // WidgetObserver overrides:
+ void OnWidgetClosing(Widget* widget) override;
+ void OnWidgetDestroying(Widget* widget) override;
+ void OnWidgetVisibilityChanging(Widget* widget, bool visible) override;
+ void OnWidgetVisibilityChanged(Widget* widget, bool visible) override;
+ void OnWidgetActivationChanged(Widget* widget, bool active) override;
+ void OnWidgetBoundsChanged(Widget* widget,
+ const gfx::Rect& new_bounds) override;
+
+ bool close_on_esc() const { return close_on_esc_; }
+ void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; }
+
+ bool close_on_deactivate() const { return close_on_deactivate_; }
+ void set_close_on_deactivate(bool close) { close_on_deactivate_ = close; }
+
+ View* GetAnchorView() const;
+ Widget* anchor_widget() const { return anchor_widget_; }
+
+ // The anchor rect is used in the absence of an assigned anchor view.
+ const gfx::Rect& anchor_rect() const { return anchor_rect_; }
+
+ BubbleBorder::Arrow arrow() const { return arrow_; }
+ void set_arrow(BubbleBorder::Arrow arrow) { arrow_ = arrow; }
+
+ BubbleBorder::Shadow shadow() const { return shadow_; }
+ void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; }
+
+ SkColor color() const { return color_; }
+ void set_color(SkColor color) {
+ color_ = color;
+ color_explicitly_set_ = true;
+ }
+
+ const gfx::Insets& margins() const { return margins_; }
+ void set_margins(const gfx::Insets& margins) { margins_ = margins; }
+
+ const gfx::Insets& anchor_view_insets() const { return anchor_view_insets_; }
+ void set_anchor_view_insets(const gfx::Insets& i) { anchor_view_insets_ = i; }
+
+ gfx::NativeView parent_window() const { return parent_window_; }
+ void set_parent_window(gfx::NativeView window) { parent_window_ = window; }
+
+ bool accept_events() const { return accept_events_; }
+ void set_accept_events(bool accept_events) { accept_events_ = accept_events; }
+
+ bool border_accepts_events() const { return border_accepts_events_; }
+ void set_border_accepts_events(bool event) { border_accepts_events_ = event; }
+
+ bool adjust_if_offscreen() const { return adjust_if_offscreen_; }
+ void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; }
+
+ CloseReason close_reason() const { return close_reason_; }
+
+ // Get the arrow's anchor rect in screen space.
+ virtual gfx::Rect GetAnchorRect() const;
+
+ // Allows delegates to provide custom parameters before widget initialization.
+ virtual void OnBeforeBubbleWidgetInit(Widget::InitParams* params,
+ Widget* widget) const;
+
+ // Sets |margins_| to a default picked for smaller bubbles.
+ void UseCompactMargins();
+
+ // Sets the bubble alignment relative to the anchor. This may only be called
+ // after calling CreateBubble.
+ void SetAlignment(BubbleBorder::BubbleAlignment alignment);
+
+ // Sets the bubble arrow paint type.
+ void SetArrowPaintType(BubbleBorder::ArrowPaintType paint_type);
+
+ // Call this method when the anchor bounds have changed to reposition the
+ // bubble. The bubble is automatically repositioned when the anchor view
+ // bounds change as a result of the widget's bounds changing.
+ void OnAnchorBoundsChanged();
+
+ protected:
+ BubbleDialogDelegateView();
+ BubbleDialogDelegateView(View* anchor_view, BubbleBorder::Arrow arrow);
+
+ // Get bubble bounds from the anchor rect and client view's preferred size.
+ virtual gfx::Rect GetBubbleBounds();
+
+ // Return a FontList to use for the title of the bubble.
+ // (The default is MediumFont).
+ virtual const gfx::FontList& GetTitleFontList() const;
+
+ // View overrides:
+ bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
+ void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
+
+ // Perform view initialization on the contents for bubble sizing.
+ virtual void Init();
+
+ // Sets the anchor view or rect and repositions the bubble. Note that if a
+ // valid view gets passed, the anchor rect will get ignored. If the view gets
+ // deleted, but no new view gets set, the last known anchor postion will get
+ // returned.
+ void SetAnchorView(View* anchor_view);
+ void SetAnchorRect(const gfx::Rect& rect);
+
+ // Resize and potentially move the bubble to fit the content's preferred size.
+ void SizeToContents();
+
+ BubbleFrameView* GetBubbleFrameView() const;
+
+ private:
+ friend class BubbleBorderDelegate;
+ friend class BubbleWindowTargeter;
+
+ FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CreateDelegate);
+ FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, NonClientHitTest);
+
+ // Update the bubble color from |theme|, unless it was explicitly set.
+ void UpdateColorsFromTheme(const ui::NativeTheme* theme);
+
+ // Handles widget visibility changes.
+ void HandleVisibilityChanged(Widget* widget, bool visible);
+
+ // Flags controlling bubble closure on the escape key and deactivation.
+ bool close_on_esc_;
+ bool close_on_deactivate_;
+
+ // The view and widget to which this bubble is anchored. Since an anchor view
+ // can be deleted without notice, we store it in the ViewStorage and retrieve
+ // it from there. It will make sure that the view is still valid.
+ const int anchor_view_storage_id_;
+ Widget* anchor_widget_;
+
+ // The anchor rect used in the absence of an anchor view.
+ mutable gfx::Rect anchor_rect_;
+
+ // The arrow's location on the bubble.
+ BubbleBorder::Arrow arrow_;
+
+ // Bubble border shadow to use.
+ BubbleBorder::Shadow shadow_;
+
+ // The background color of the bubble; and flag for when it's explicitly set.
+ SkColor color_;
+ bool color_explicitly_set_;
+
+ // The margins between the content and the inside of the border.
+ gfx::Insets margins_;
+
+ // Insets applied to the |anchor_view_| bounds.
+ gfx::Insets anchor_view_insets_;
+
+ // Specifies whether the bubble (or its border) handles mouse events, etc.
+ bool accept_events_;
+ bool border_accepts_events_;
+
+ // If true (defaults to true), the arrow may be mirrored and moved to fit the
+ // bubble on screen better. It would be a no-op if the bubble has no arrow.
+ bool adjust_if_offscreen_;
+
+ // Parent native window of the bubble.
+ gfx::NativeView parent_window_;
+
+ CloseReason close_reason_;
+
+ DISALLOW_COPY_AND_ASSIGN(BubbleDialogDelegateView);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_BUBBLE_BUBBLE_DELEGATE2_H_
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
index 64bf37c..0c1220c 100644
--- a/ui/views/bubble/bubble_frame_view.cc
+++ b/ui/views/bubble/bubble_frame_view.cc
@@ -78,7 +78,6 @@ BubbleFrameView::BubbleFrameView(const gfx::Insets& title_margins,
title_icon_(new views::ImageView()),
title_(nullptr),
close_(nullptr),
- titlebar_extra_view_(nullptr),
footnote_container_(nullptr),
close_button_clicked_(false) {
AddChildView(title_icon_);
@@ -308,19 +307,6 @@ void BubbleFrameView::Layout() {
title_icon_size.width() + title_label_size.width() + padding);
bounds.set_height(title_height);
- if (titlebar_extra_view_) {
- const int extra_width = close_->x() - bounds.right();
- gfx::Size size = titlebar_extra_view_->GetPreferredSize();
- size.SetToMin(gfx::Size(std::max(0, extra_width), size.height()));
- gfx::Rect titlebar_extra_view_bounds(
- close_->x() - size.width(),
- bounds.y(),
- size.width(),
- bounds.height());
- titlebar_extra_view_bounds.Subtract(bounds);
- titlebar_extra_view_->SetBoundsRect(titlebar_extra_view_bounds);
- }
-
if (footnote_container_) {
gfx::Rect local_bounds = GetContentsBounds();
int height = footnote_container_->GetHeightForWidth(local_bounds.width());
@@ -334,11 +320,6 @@ const char* BubbleFrameView::GetClassName() const {
return kViewClassName;
}
-void BubbleFrameView::ChildPreferredSizeChanged(View* child) {
- if (child == titlebar_extra_view_ || child == title_)
- Layout();
-}
-
void BubbleFrameView::OnThemeChanged() {
UpdateWindowTitle();
ResetWindowControls();
@@ -368,21 +349,11 @@ void BubbleFrameView::SetBubbleBorder(scoped_ptr<BubbleBorder> border) {
set_background(new views::BubbleBackground(bubble_border_));
}
-void BubbleFrameView::SetTitlebarExtraView(scoped_ptr<View> view) {
- if (!view)
- return;
-
- DCHECK(!titlebar_extra_view_);
- titlebar_extra_view_ = view.release();
- AddChildView(titlebar_extra_view_);
-}
-
-void BubbleFrameView::SetFootnoteView(scoped_ptr<View> view) {
+void BubbleFrameView::SetFootnoteView(View* view) {
if (!view)
return;
DCHECK(!footnote_container_);
-
footnote_container_ = new views::View();
footnote_container_->SetLayoutManager(
new BoxLayout(BoxLayout::kVertical, content_margins_.left(),
@@ -391,7 +362,7 @@ void BubbleFrameView::SetFootnoteView(scoped_ptr<View> view) {
Background::CreateSolidBackground(kFootnoteBackgroundColor));
footnote_container_->SetBorder(
Border::CreateSolidSidedBorder(1, 0, 0, 0, kFootnoteBorderColor));
- footnote_container_->AddChildView(view.release());
+ footnote_container_->AddChildView(view);
AddChildView(footnote_container_);
}
@@ -511,8 +482,6 @@ gfx::Size BubbleFrameView::GetSizeForClientSize(
title_bar_width += title_icon_size.width();
if (close_->visible())
title_bar_width += close_->width() + 1;
- if (titlebar_extra_view_)
- title_bar_width += titlebar_extra_view_->GetPreferredSize().width();
gfx::Size size(client_size);
gfx::Insets client_insets = GetInsets();
diff --git a/ui/views/bubble/bubble_frame_view.h b/ui/views/bubble/bubble_frame_view.h
index ef19762..f9d3f30 100644
--- a/ui/views/bubble/bubble_frame_view.h
+++ b/ui/views/bubble/bubble_frame_view.h
@@ -59,7 +59,6 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
gfx::Size GetMaximumSize() const override;
void Layout() override;
const char* GetClassName() const override;
- void ChildPreferredSizeChanged(View* child) override;
void OnThemeChanged() override;
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
@@ -72,9 +71,7 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
gfx::Insets content_margins() const { return content_margins_; }
- void SetTitlebarExtraView(scoped_ptr<View> view);
-
- void SetFootnoteView(scoped_ptr<View> view);
+ void SetFootnoteView(View* view);
// Given the size of the contents and the rect to point at, returns the bounds
// of the bubble window. The bubble's arrow location may change if the bubble
@@ -124,10 +121,6 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
Label* title_;
LabelButton* close_;
- // When supplied, this view is placed in the titlebar between the title and
- // (x) close button.
- View* titlebar_extra_view_;
-
// A view to contain the footnote view, if it exists.
View* footnote_container_;
diff --git a/ui/views/examples/widget_example.cc b/ui/views/examples/widget_example.cc
index bcfb451..0165de3 100644
--- a/ui/views/examples/widget_example.cc
+++ b/ui/views/examples/widget_example.cc
@@ -28,7 +28,6 @@ class DialogExample : public DialogDelegateView {
~DialogExample() override;
base::string16 GetWindowTitle() const override;
View* CreateExtraView() override;
- View* CreateTitlebarExtraView() override;
View* CreateFootnoteView() override;
};
@@ -61,12 +60,6 @@ View* DialogExample::CreateExtraView() {
return button;
}
-View* DialogExample::CreateTitlebarExtraView() {
- Label* label = new Label(ASCIIToUTF16("Extra view!"));
- label->SetEnabledColor(SK_ColorBLUE);
- return label;
-}
-
View* DialogExample::CreateFootnoteView() {
return new Label(ASCIIToUTF16("Footnote label!"));
}
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index a6707a2..584513d 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -49,6 +49,8 @@
'bubble/bubble_border.h',
'bubble/bubble_delegate.cc',
'bubble/bubble_delegate.h',
+ 'bubble/bubble_dialog_delegate.cc',
+ 'bubble/bubble_dialog_delegate.h',
'bubble/bubble_frame_view.cc',
'bubble/bubble_frame_view.h',
'button_drag_utils.cc',
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index 5f069ef..5a115e5 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -54,10 +54,13 @@ void LayoutButton(LabelButton* button, gfx::Rect* row_bounds) {
DialogClientView::DialogClientView(Widget* owner, View* contents_view)
: ClientView(owner, contents_view),
+ button_row_insets_(0,
+ kButtonHEdgeMarginNew,
+ kButtonVEdgeMarginNew,
+ kButtonHEdgeMarginNew),
ok_button_(NULL),
cancel_button_(NULL),
extra_view_(NULL),
- footnote_view_(NULL),
delegate_allowed_close_(false) {}
DialogClientView::~DialogClientView() {
@@ -86,8 +89,6 @@ void DialogClientView::UpdateDialogButtons() {
if (buttons & ui::DIALOG_BUTTON_OK) {
if (!ok_button_) {
ok_button_ = CreateDialogButton(ui::DIALOG_BUTTON_OK);
- if (!(buttons & ui::DIALOG_BUTTON_CANCEL))
- ok_button_->AddAccelerator(escape);
AddChildView(ok_button_);
}
@@ -110,8 +111,8 @@ void DialogClientView::UpdateDialogButtons() {
cancel_button_ = NULL;
}
- // Use the escape key to close the window if there are no dialog buttons.
- if (!has_dialog_buttons())
+ // Use the escape key to close the window if there is no cancel button.
+ if (!cancel_button_)
AddAccelerator(escape);
else
ResetAccelerators();
@@ -167,31 +168,12 @@ gfx::Size DialogClientView::GetPreferredSize() const {
size.Enlarge(0, contents_size.height());
size.set_width(std::max(size.width(), contents_size.width()));
- // Increase the size as needed to fit the footnote view.
- if (ShouldShow(footnote_view_)) {
- gfx::Size footnote_size = footnote_view_->GetPreferredSize();
- if (!footnote_size.IsEmpty())
- size.set_width(std::max(size.width(), footnote_size.width()));
-
- int footnote_height = footnote_view_->GetHeightForWidth(size.width());
- size.Enlarge(0, footnote_height);
- }
-
return size;
}
void DialogClientView::Layout() {
gfx::Rect bounds = GetContentsBounds();
- // Layout the footnote view.
- if (ShouldShow(footnote_view_)) {
- const int height = footnote_view_->GetHeightForWidth(bounds.width());
- footnote_view_->SetBounds(bounds.x(), bounds.bottom() - height,
- bounds.width(), height);
- if (height != 0)
- bounds.Inset(0, 0, 0, height);
- }
-
// Layout the row containing the buttons and the extra view.
if (has_dialog_buttons() || ShouldShow(extra_view_)) {
bounds.Inset(GetButtonRowInsets());
@@ -242,7 +224,6 @@ void DialogClientView::ViewHierarchyChanged(
if (details.is_add && details.child == this) {
UpdateDialogButtons();
CreateExtraView();
- CreateFootnoteView();
} else if (!details.is_add && details.child != this) {
if (details.child == ok_button_)
ok_button_ = nullptr;
@@ -250,8 +231,6 @@ void DialogClientView::ViewHierarchyChanged(
cancel_button_ = nullptr;
else if (details.child == extra_view_)
extra_view_ = nullptr;
- else if (details.child == footnote_view_)
- footnote_view_ = nullptr;
}
SetupFocusChain();
@@ -292,7 +271,6 @@ DialogClientView::DialogClientView(View* contents_view)
ok_button_(NULL),
cancel_button_(NULL),
extra_view_(NULL),
- footnote_view_(NULL),
delegate_allowed_close_(false) {}
DialogDelegate* DialogClientView::GetDialogDelegate() const {
@@ -310,17 +288,8 @@ void DialogClientView::CreateExtraView() {
}
}
-void DialogClientView::CreateFootnoteView() {
- if (footnote_view_)
- return;
-
- footnote_view_ = GetDialogDelegate()->CreateFootnoteView();
- if (footnote_view_)
- AddChildView(footnote_view_);
-}
-
void DialogClientView::ChildPreferredSizeChanged(View* child) {
- if (child == footnote_view_ || child == extra_view_)
+ if (child == extra_view_)
Layout();
}
@@ -368,14 +337,10 @@ int DialogClientView::GetButtonsAndExtraViewRowHeight() const {
}
gfx::Insets DialogClientView::GetButtonRowInsets() const {
- // NOTE: The insets only apply to the buttons, extra view, and footnote view.
- return GetButtonsAndExtraViewRowHeight() == 0 ? gfx::Insets() :
- gfx::Insets(0, kButtonHEdgeMarginNew,
- kButtonVEdgeMarginNew, kButtonHEdgeMarginNew);
+ return GetButtonsAndExtraViewRowHeight() == 0 ? gfx::Insets()
+ : button_row_insets_;
}
-
-
void DialogClientView::SetupFocusChain() {
// Create a vector of child views in the order of intended focus.
std::vector<View*> child_views;
@@ -388,7 +353,6 @@ void DialogClientView::SetupFocusChain() {
child_views.push_back(cancel_button_);
child_views.push_back(ok_button_);
}
- child_views.push_back(footnote_view_);
// Remove all null views from the vector.
child_views.erase(
diff --git a/ui/views/window/dialog_client_view.h b/ui/views/window/dialog_client_view.h
index 8f4e0fc..60080b0 100644
--- a/ui/views/window/dialog_client_view.h
+++ b/ui/views/window/dialog_client_view.h
@@ -19,14 +19,13 @@ class Widget;
// DialogClientView provides adornments for a dialog's content view, including
// custom-labeled [OK] and [Cancel] buttons with [Enter] and [Esc] accelerators.
-// The view also displays the delegate's extra view alongside the buttons and
-// the delegate's footnote view below the buttons. The view appears like below.
-// NOTE: The contents view is not inset on the top or side client view edges.
+// The view also displays the delegate's extra view alongside the buttons. The
+// view appears like below. NOTE: The contents view is not inset on the top or
+// side client view edges.
// +------------------------------+
// | Contents View |
// +------------------------------+
// | [Extra View] [OK] [Cancel] |
-// | [ Footnote View ] |
// +------------------------------+
class VIEWS_EXPORT DialogClientView : public ClientView,
public ButtonListener {
@@ -61,6 +60,10 @@ class VIEWS_EXPORT DialogClientView : public ClientView,
// ButtonListener implementation:
void ButtonPressed(Button* sender, const ui::Event& event) override;
+ void set_button_row_insets(const gfx::Insets& insets) {
+ button_row_insets_ = insets;
+ }
+
protected:
// For testing.
explicit DialogClientView(View* contents_view);
@@ -71,9 +74,6 @@ class VIEWS_EXPORT DialogClientView : public ClientView,
// Create and add the extra view, if supplied by the delegate.
void CreateExtraView();
- // Creates and adds the footnote view, if supplied by the delegate.
- void CreateFootnoteView();
-
// View implementation.
void ChildPreferredSizeChanged(View* child) override;
void ChildVisibilityChanged(View* child) override;
@@ -93,6 +93,9 @@ class VIEWS_EXPORT DialogClientView : public ClientView,
// Returns the insets for the buttons and extra view.
gfx::Insets GetButtonRowInsets() const;
+ // How much to inset the button row.
+ gfx::Insets button_row_insets_;
+
// Sets up the focus chain for the child views. This is required since the
// delegate may choose to add/remove views at any time.
void SetupFocusChain();
@@ -104,9 +107,6 @@ class VIEWS_EXPORT DialogClientView : public ClientView,
// The extra view shown in the row of buttons; may be NULL.
View* extra_view_;
- // The footnote view shown below the buttons; may be NULL.
- View* footnote_view_;
-
// True if we've notified the delegate the window is closing and the delegate
// allowed the close. In some situations it's possible to get two closes (see
// http://crbug.com/71940). This is used to avoid notifying the delegate
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc
index 751b21c..f4f72ee 100644
--- a/ui/views/window/dialog_client_view_unittest.cc
+++ b/ui/views/window/dialog_client_view_unittest.cc
@@ -30,7 +30,6 @@ class TestDialogClientView : public DialogClientView {
void CreateExtraViews() {
CreateExtraView();
- CreateFootnoteView();
}
private:
@@ -44,8 +43,7 @@ class DialogClientViewTest : public ViewsTestBase,
public:
DialogClientViewTest()
: dialog_buttons_(ui::DIALOG_BUTTON_NONE),
- extra_view_(NULL),
- footnote_view_(NULL) {}
+ extra_view_(nullptr) {}
~DialogClientViewTest() override {}
// testing::Test implementation.
@@ -65,7 +63,6 @@ class DialogClientViewTest : public ViewsTestBase,
*padding = *extra_view_padding_;
return extra_view_padding_.get() != nullptr;
}
- View* CreateFootnoteView() override { return footnote_view_; }
int GetDialogButtons() const override { return dialog_buttons_; }
protected:
@@ -106,13 +103,6 @@ class DialogClientViewTest : public ViewsTestBase,
client_view_->Layout();
}
- // Sets the footnote view.
- void SetFootnoteView(View* view) {
- DCHECK(!footnote_view_);
- footnote_view_ = view;
- client_view_->CreateExtraViews();
- }
-
TestDialogClientView* client_view() { return client_view_.get(); }
private:
@@ -124,7 +114,6 @@ class DialogClientViewTest : public ViewsTestBase,
int dialog_buttons_;
View* extra_view_; // weak
scoped_ptr<int> extra_view_padding_; // Null by default.
- View* footnote_view_; // weak
DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest);
};
@@ -256,43 +245,4 @@ TEST_F(DialogClientViewTest, LayoutWithButtons) {
EXPECT_GT(width_of_extra_view, extra_view->bounds().width());
}
-// Test the effect of the footnote view on layout.
-TEST_F(DialogClientViewTest, LayoutWithFootnote) {
- CheckContentsIsSetToPreferredSize();
- gfx::Size no_footnote_size = client_view()->bounds().size();
-
- View* footnote_view = new StaticSizedView(gfx::Size(200, 200));
- SetFootnoteView(footnote_view);
- CheckContentsIsSetToPreferredSize();
- EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
- EXPECT_EQ(200, footnote_view->bounds().height());
- gfx::Size with_footnote_size = client_view()->bounds().size();
- EXPECT_EQ(with_footnote_size.width(), footnote_view->bounds().width());
-
- SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
- CheckContentsIsSetToPreferredSize();
- EXPECT_LE(with_footnote_size.height(), client_view()->bounds().height());
- EXPECT_LE(with_footnote_size.width(), client_view()->bounds().width());
- gfx::Size with_footnote_and_button_size = client_view()->bounds().size();
-
- SetDialogButtons(ui::DIALOG_BUTTON_NONE);
- footnote_view->SetVisible(false);
- CheckContentsIsSetToPreferredSize();
- EXPECT_EQ(no_footnote_size.height(), client_view()->bounds().height());
- EXPECT_EQ(no_footnote_size.width(), client_view()->bounds().width());
-}
-
-// Test that GetHeightForWidth is respected for the footnote view.
-TEST_F(DialogClientViewTest, LayoutWithFootnoteHeightForWidth) {
- CheckContentsIsSetToPreferredSize();
- gfx::Size no_footnote_size = client_view()->bounds().size();
-
- View* footnote_view = new ProportionallySizedView(3);
- SetFootnoteView(footnote_view);
- CheckContentsIsSetToPreferredSize();
- EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
- EXPECT_EQ(footnote_view->bounds().width() * 3,
- footnote_view->bounds().height());
-}
-
} // namespace views
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index e6b179e..a7305d2 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -94,10 +94,6 @@ bool DialogDelegate::GetExtraViewPadding(int* padding) {
return false;
}
-View* DialogDelegate::CreateTitlebarExtraView() {
- return NULL;
-}
-
View* DialogDelegate::CreateFootnoteView() {
return NULL;
}
@@ -206,10 +202,8 @@ NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) {
border->set_use_theme_background_color(true);
frame->SetBubbleBorder(std::move(border));
DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();
- if (delegate) {
- frame->SetTitlebarExtraView(
- make_scoped_ptr(delegate->CreateTitlebarExtraView()));
- }
+ if (delegate)
+ frame->SetFootnoteView(delegate->CreateFootnoteView());
return frame;
}
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h
index 68b1f20..96bb96e 100644
--- a/ui/views/window/dialog_delegate.h
+++ b/ui/views/window/dialog_delegate.h
@@ -56,11 +56,6 @@ class VIEWS_EXPORT DialogDelegate : public ui::DialogModel,
// If a custom padding should be used, returns true and populates |padding|.
virtual bool GetExtraViewPadding(int* padding);
- // Override this function to display an extra view in the titlebar.
- // Overrides may construct the view; this will only be called once per dialog.
- // Note: this only works for new style dialogs.
- virtual View* CreateTitlebarExtraView();
-
// Override this function to display a footnote view below the buttons.
// Overrides may construct the view; this will only be called once per dialog.
virtual View* CreateFootnoteView();