Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: chrome/browser/ui/views/global_error_bubble_view.cc

Issue 1846033002: Switch GlobalErrorBubbleView to a BubbleDialogDelegate. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/global_error_bubble_view.h" 5 #include "chrome/browser/ui/views/global_error_bubble_view.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/ui/global_error/global_error.h" 12 #include "chrome/browser/ui/global_error/global_error.h"
13 #include "chrome/browser/ui/global_error/global_error_service.h" 13 #include "chrome/browser/ui/global_error/global_error_service.h"
14 #include "chrome/browser/ui/global_error/global_error_service_factory.h" 14 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
15 #include "chrome/browser/ui/views/elevation_icon_setter.h" 15 #include "chrome/browser/ui/views/elevation_icon_setter.h"
16 #include "chrome/browser/ui/views/frame/browser_view.h" 16 #include "chrome/browser/ui/views/frame/browser_view.h"
17 #include "chrome/browser/ui/views/toolbar/app_menu_button.h" 17 #include "chrome/browser/ui/views/toolbar/app_menu_button.h"
18 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" 18 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
19 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/gfx/image/image.h" 20 #include "ui/gfx/image/image.h"
21 #include "ui/views/bubble/bubble_frame_view.h" 21 #include "ui/views/bubble/bubble_frame_view.h"
22 #include "ui/views/controls/button/blue_button.h" 22 #include "ui/views/controls/button/blue_button.h"
23 #include "ui/views/controls/button/label_button.h" 23 #include "ui/views/controls/button/label_button.h"
24 #include "ui/views/controls/image_view.h" 24 #include "ui/views/controls/image_view.h"
25 #include "ui/views/controls/label.h" 25 #include "ui/views/controls/label.h"
26 #include "ui/views/layout/grid_layout.h" 26 #include "ui/views/layout/grid_layout.h"
27 #include "ui/views/layout/layout_constants.h" 27 #include "ui/views/layout/layout_constants.h"
28 #include "ui/views/window/dialog_client_view.h"
28 29
29 namespace { 30 namespace {
30 31
31 enum { 32 const int kMaxBubbleViewWidth = 362;
32 TAG_ACCEPT_BUTTON = 1,
33 TAG_CANCEL_BUTTON,
34 };
35
36 const int kMaxBubbleViewWidth = 262;
37 33
38 // The vertical inset of the app bubble anchor from the app menu button. 34 // The vertical inset of the app bubble anchor from the app menu button.
39 const int kAnchorVerticalInset = 5; 35 const int kAnchorVerticalInset = 5;
40 36
41 const int kBubblePadding = 19;
42
43 // Spacing between bubble text and buttons.
44 const int kLabelToButtonVerticalSpacing = 14;
45
46 } // namespace 37 } // namespace
47 38
48 // GlobalErrorBubbleViewBase --------------------------------------------------- 39 // GlobalErrorBubbleViewBase ---------------------------------------------------
49 40
50 // static 41 // static
51 GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowStandardBubbleView( 42 GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowStandardBubbleView(
52 Browser* browser, 43 Browser* browser,
53 const base::WeakPtr<GlobalErrorWithStandardBubble>& error) { 44 const base::WeakPtr<GlobalErrorWithStandardBubble>& error) {
54 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); 45 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
55 views::View* app_menu_button = browser_view->toolbar()->app_menu_button(); 46 views::View* app_menu_button = browser_view->toolbar()->app_menu_button();
56 GlobalErrorBubbleView* bubble_view = new GlobalErrorBubbleView( 47 GlobalErrorBubbleView* bubble_view = new GlobalErrorBubbleView(
57 app_menu_button, views::BubbleBorder::TOP_RIGHT, browser, error); 48 app_menu_button, views::BubbleBorder::TOP_RIGHT, browser, error);
58 views::BubbleDelegateView::CreateBubble(bubble_view); 49 views::BubbleDialogDelegateView::CreateBubble(bubble_view);
59 bubble_view->GetWidget()->Show(); 50 bubble_view->GetWidget()->Show();
60 return bubble_view; 51 return bubble_view;
61 } 52 }
62 53
63 // GlobalErrorBubbleView ------------------------------------------------------- 54 // GlobalErrorBubbleView -------------------------------------------------------
64 55
65 GlobalErrorBubbleView::GlobalErrorBubbleView( 56 GlobalErrorBubbleView::GlobalErrorBubbleView(
66 views::View* anchor_view, 57 views::View* anchor_view,
67 views::BubbleBorder::Arrow arrow, 58 views::BubbleBorder::Arrow arrow,
68 Browser* browser, 59 Browser* browser,
69 const base::WeakPtr<GlobalErrorWithStandardBubble>& error) 60 const base::WeakPtr<GlobalErrorWithStandardBubble>& error)
70 : BubbleDelegateView(anchor_view, arrow), 61 : BubbleDialogDelegateView(anchor_view, arrow),
71 browser_(browser), 62 browser_(browser),
72 error_(error) { 63 error_(error) {}
73 // Set content margins to left-align the bubble text with the title.
74 // BubbleFrameView adds enough padding below title, no top padding needed.
75 set_margins(gfx::Insets(0, kBubblePadding, kBubblePadding, kBubblePadding));
76 64
65 GlobalErrorBubbleView::~GlobalErrorBubbleView() {
66 // |elevation_icon_setter_| references |accept_button_|, so make sure it is
msw 2016/04/04 17:13:18 nit: there is no |accept_button_| member, update c
Evan Stade 2016/04/04 22:59:07 verified this is no longer needed, removed.
67 // destroyed before |accept_button_|.
68 elevation_icon_setter_.reset();
69 }
70
71 base::string16 GlobalErrorBubbleView::GetWindowTitle() const {
72 return error_->GetBubbleViewTitle();
73 }
74
75 gfx::ImageSkia GlobalErrorBubbleView::GetWindowIcon() {
76 gfx::Image image = error_->GetBubbleViewIcon();
77 DCHECK(!image.IsEmpty());
78 return *image.ToImageSkia();
79 }
80
81 bool GlobalErrorBubbleView::ShouldShowWindowIcon() const {
82 return true;
83 }
84
85 void GlobalErrorBubbleView::WindowClosing() {
86 if (error_)
87 error_->BubbleViewDidClose(browser_);
88 }
89
90 void GlobalErrorBubbleView::Init() {
77 // Compensate for built-in vertical padding in the anchor view's image. 91 // Compensate for built-in vertical padding in the anchor view's image.
78 set_anchor_view_insets( 92 set_anchor_view_insets(
79 gfx::Insets(kAnchorVerticalInset, 0, kAnchorVerticalInset, 0)); 93 gfx::Insets(kAnchorVerticalInset, 0, kAnchorVerticalInset, 0));
80 94
81 std::vector<base::string16> message_strings(error_->GetBubbleViewMessages()); 95 std::vector<base::string16> message_strings(error_->GetBubbleViewMessages());
82 std::vector<views::Label*> message_labels; 96 std::vector<views::Label*> message_labels;
83 for (size_t i = 0; i < message_strings.size(); ++i) { 97 for (size_t i = 0; i < message_strings.size(); ++i) {
84 views::Label* message_label = new views::Label(message_strings[i]); 98 views::Label* message_label = new views::Label(message_strings[i]);
85 message_label->SetMultiLine(true); 99 message_label->SetMultiLine(true);
86 message_label->SizeToFit(kMaxBubbleViewWidth);
87 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 100 message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
88 message_labels.push_back(message_label); 101 message_labels.push_back(message_label);
89 } 102 }
90 103
91 base::string16 accept_string(error_->GetBubbleViewAcceptButtonLabel());
92 scoped_ptr<views::BlueButton> accept_button(
93 new views::BlueButton(this, accept_string));
94 accept_button->SetIsDefault(true);
95 accept_button->set_tag(TAG_ACCEPT_BUTTON);
96
97 if (error_->ShouldAddElevationIconToAcceptButton())
98 elevation_icon_setter_.reset(
99 new ElevationIconSetter(
100 accept_button.get(),
101 base::Bind(&GlobalErrorBubbleView::SizeToContents,
102 base::Unretained(this))));
103
104 base::string16 cancel_string(error_->GetBubbleViewCancelButtonLabel());
105 scoped_ptr<views::LabelButton> cancel_button;
106 if (!cancel_string.empty()) {
107 cancel_button.reset(new views::LabelButton(this, cancel_string));
108 cancel_button->SetStyle(views::Button::STYLE_BUTTON);
109 cancel_button->set_tag(TAG_CANCEL_BUTTON);
110 }
111
112 views::GridLayout* layout = new views::GridLayout(this); 104 views::GridLayout* layout = new views::GridLayout(this);
113 SetLayoutManager(layout); 105 SetLayoutManager(layout);
114 106
115 // First row, message labels. 107 // First row, message labels.
116 views::ColumnSet* cs = layout->AddColumnSet(0); 108 views::ColumnSet* cs = layout->AddColumnSet(0);
117 cs->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 109 cs->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
118 1, views::GridLayout::USE_PREF, 0, 0); 110 views::GridLayout::FIXED, kMaxBubbleViewWidth, 0);
119
120 // Second row, accept and cancel button.
121 cs = layout->AddColumnSet(1);
122 cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing);
123 cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING,
124 0, views::GridLayout::USE_PREF, 0, 0);
125 if (cancel_button.get()) {
126 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
127 cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING,
128 0, views::GridLayout::USE_PREF, 0, 0);
129 }
130 111
131 for (size_t i = 0; i < message_labels.size(); ++i) { 112 for (size_t i = 0; i < message_labels.size(); ++i) {
132 layout->StartRow(1, 0); 113 layout->StartRow(1, 0);
133 layout->AddView(message_labels[i]); 114 layout->AddView(message_labels[i]);
134 if (i < message_labels.size() - 1) 115 if (i < message_labels.size() - 1)
135 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 116 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
136 } 117 }
137 layout->AddPaddingRow(0, kLabelToButtonVerticalSpacing);
138
139 layout->StartRow(0, 1);
140 layout->AddView(accept_button.release());
141 if (cancel_button.get())
142 layout->AddView(cancel_button.release());
143
144 // Adjust the message label size in case buttons are too long.
145 for (size_t i = 0; i < message_labels.size(); ++i)
146 message_labels[i]->SizeToFit(layout->GetPreferredSize(this).width());
147 118
148 // These bubbles show at times where activation is sporadic (like at startup, 119 // These bubbles show at times where activation is sporadic (like at startup,
149 // or a new window opening). Make sure the bubble doesn't disappear before the 120 // or a new window opening). Make sure the bubble doesn't disappear before the
150 // user sees it, if the bubble needs to be acknowledged. 121 // user sees it, if the bubble needs to be acknowledged.
151 set_close_on_deactivate(error_->ShouldCloseOnDeactivate()); 122 set_close_on_deactivate(error_->ShouldCloseOnDeactivate());
152 } 123 }
153 124
154 GlobalErrorBubbleView::~GlobalErrorBubbleView() { 125 void GlobalErrorBubbleView::UpdateButton(views::LabelButton* button,
155 // |elevation_icon_setter_| references |accept_button_|, so make sure it is 126 ui::DialogButton type) {
156 // destroyed before |accept_button_|. 127 BubbleDialogDelegateView::UpdateButton(button, type);
157 elevation_icon_setter_.reset(); 128 if (type == ui::DIALOG_BUTTON_OK &&
158 } 129 error_->ShouldAddElevationIconToAcceptButton()) {
159 130 elevation_icon_setter_.reset(new ElevationIconSetter(
160 void GlobalErrorBubbleView::ButtonPressed(views::Button* sender, 131 button, base::Bind(&GlobalErrorBubbleView::SizeToContents,
161 const ui::Event& event) { 132 base::Unretained(this))));
162 if (error_) {
163 if (sender->tag() == TAG_ACCEPT_BUTTON)
164 error_->BubbleViewAcceptButtonPressed(browser_);
165 else if (sender->tag() == TAG_CANCEL_BUTTON)
166 error_->BubbleViewCancelButtonPressed(browser_);
167 else
168 NOTREACHED();
169 } 133 }
170 GetWidget()->Close();
171 }
172
173 base::string16 GlobalErrorBubbleView::GetWindowTitle() const {
174 return error_->GetBubbleViewTitle();
175 }
176
177 gfx::ImageSkia GlobalErrorBubbleView::GetWindowIcon() {
178 gfx::Image image = error_->GetBubbleViewIcon();
179 DCHECK(!image.IsEmpty());
180 return *image.ToImageSkia();
181 }
182
183 bool GlobalErrorBubbleView::ShouldShowWindowIcon() const {
184 return true;
185 }
186
187 void GlobalErrorBubbleView::WindowClosing() {
188 if (error_)
189 error_->BubbleViewDidClose(browser_);
190 } 134 }
191 135
192 bool GlobalErrorBubbleView::ShouldShowCloseButton() const { 136 bool GlobalErrorBubbleView::ShouldShowCloseButton() const {
193 return error_ && error_->ShouldShowCloseButton(); 137 return error_ && error_->ShouldShowCloseButton();
194 } 138 }
195 139
140 bool GlobalErrorBubbleView::ShouldDefaultButtonBeBlue() const {
141 return true;
142 }
143
144 base::string16 GlobalErrorBubbleView::GetDialogButtonLabel(
145 ui::DialogButton button) const {
146 return button == ui::DIALOG_BUTTON_OK
147 ? error_->GetBubbleViewAcceptButtonLabel()
148 : error_->GetBubbleViewCancelButtonLabel();
149 }
150
151 int GlobalErrorBubbleView::GetDialogButtons() const {
152 return ui::DIALOG_BUTTON_OK |
153 (error_->GetBubbleViewCancelButtonLabel().empty()
154 ? 0
155 : ui::DIALOG_BUTTON_CANCEL);
156 }
157
158 bool GlobalErrorBubbleView::Cancel() {
159 error_->BubbleViewCancelButtonPressed(browser_);
160 return true;
161 }
162
163 bool GlobalErrorBubbleView::Accept() {
164 error_->BubbleViewAcceptButtonPressed(browser_);
165 return true;
166 }
167
168 bool GlobalErrorBubbleView::Close() {
169 return true;
msw 2016/04/04 17:13:18 I think this is slightly non-obvious and deserves
Evan Stade 2016/04/04 22:59:07 I don't know how to complete this sentence, I'm ju
msw 2016/04/05 00:25:26 You could say "so that closing via dismissal isn't
Evan Stade 2016/04/05 03:13:18 Done.
Finnur 2016/04/05 15:19:13 Late to the party... Although I did some bubble
170 }
171
196 void GlobalErrorBubbleView::CloseBubbleView() { 172 void GlobalErrorBubbleView::CloseBubbleView() {
197 GetWidget()->Close(); 173 GetWidget()->Close();
198 } 174 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/global_error_bubble_view.h ('k') | ui/views/window/dialog_client_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698