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

Side by Side Diff: chrome/browser/ui/views/extensions/extension_message_bubble_view.cc

Issue 1858773006: [Extensions UI] Use the ExtensionMessageBubbleBridge for Views platforms (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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/extensions/extension_message_bubble_view.h" 5 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
13 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
14 #include "chrome/browser/ui/layout_constants.h" 13 #include "chrome/browser/ui/layout_constants.h"
14 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_bubble_delegate.h"
15 #include "chrome/browser/ui/view_ids.h" 15 #include "chrome/browser/ui/view_ids.h"
16 #include "chrome/grit/locale_settings.h" 16 #include "chrome/grit/locale_settings.h"
17 #include "ui/accessibility/ax_view_state.h" 17 #include "ui/accessibility/ax_view_state.h"
18 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/views/controls/button/label_button.h" 19 #include "ui/views/controls/button/label_button.h"
20 #include "ui/views/controls/label.h" 20 #include "ui/views/controls/label.h"
21 #include "ui/views/controls/link.h" 21 #include "ui/views/controls/link.h"
22 #include "ui/views/layout/grid_layout.h" 22 #include "ui/views/layout/grid_layout.h"
23 #include "ui/views/view.h" 23 #include "ui/views/view.h"
24 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
(...skipping 12 matching lines...) Expand all
37 // How long to wait until showing the bubble (in seconds). 37 // How long to wait until showing the bubble (in seconds).
38 int g_bubble_appearance_wait_time = 5; 38 int g_bubble_appearance_wait_time = 5;
39 39
40 } // namespace 40 } // namespace
41 41
42 namespace extensions { 42 namespace extensions {
43 43
44 ExtensionMessageBubbleView::ExtensionMessageBubbleView( 44 ExtensionMessageBubbleView::ExtensionMessageBubbleView(
45 views::View* anchor_view, 45 views::View* anchor_view,
46 views::BubbleBorder::Arrow arrow_location, 46 views::BubbleBorder::Arrow arrow_location,
47 std::unique_ptr<extensions::ExtensionMessageBubbleController> controller) 47 std::unique_ptr<ToolbarActionsBarBubbleDelegate> delegate)
48 : BubbleDelegateView(anchor_view, arrow_location), 48 : BubbleDelegateView(anchor_view, arrow_location),
49 controller_(std::move(controller)), 49 delegate_(std::move(delegate)),
50 anchor_view_(anchor_view), 50 anchor_view_(anchor_view),
51 headline_(NULL), 51 headline_(NULL),
52 learn_more_(NULL), 52 learn_more_(NULL),
53 dismiss_button_(NULL), 53 dismiss_button_(NULL),
54 link_clicked_(false), 54 link_clicked_(false),
55 action_taken_(false), 55 action_taken_(false),
56 weak_factory_(this) { 56 weak_factory_(this) {
57 DCHECK(anchor_view->GetWidget()); 57 DCHECK(anchor_view->GetWidget());
58 set_close_on_deactivate(controller_->CloseOnDeactivate()); 58 set_close_on_deactivate(delegate_->ShouldCloseOnDeactivate());
59 set_close_on_esc(true); 59 set_close_on_esc(true);
60 60
61 // Compensate for built-in vertical padding in the anchor view's image. 61 // Compensate for built-in vertical padding in the anchor view's image.
62 set_anchor_view_insets(gfx::Insets( 62 set_anchor_view_insets(gfx::Insets(
63 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0)); 63 GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
64 } 64 }
65 65
66 void ExtensionMessageBubbleView::Show() { 66 void ExtensionMessageBubbleView::Show() {
67 // Not showing the bubble right away (during startup) has a few benefits: 67 // Not showing the bubble right away (during startup) has a few benefits:
68 // We don't have to worry about focus being lost due to the Omnibox (or to 68 // We don't have to worry about focus being lost due to the Omnibox (or to
69 // other things that want focus at startup). This allows Esc to work to close 69 // other things that want focus at startup). This allows Esc to work to close
70 // the bubble and also solves the keyboard accessibility problem that comes 70 // the bubble and also solves the keyboard accessibility problem that comes
71 // with focus being lost (we don't have a good generic mechanism of injecting 71 // with focus being lost (we don't have a good generic mechanism of injecting
72 // bubbles into the focus cycle). Another benefit of delaying the show is 72 // bubbles into the focus cycle). Another benefit of delaying the show is
73 // that fade-in works (the fade-in isn't apparent if the the bubble appears at 73 // that fade-in works (the fade-in isn't apparent if the the bubble appears at
74 // startup). 74 // startup).
75 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 75 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
76 FROM_HERE, base::Bind(&ExtensionMessageBubbleView::ShowBubble, 76 FROM_HERE, base::Bind(&ExtensionMessageBubbleView::ShowBubble,
77 weak_factory_.GetWeakPtr()), 77 weak_factory_.GetWeakPtr()),
78 base::TimeDelta::FromSeconds(g_bubble_appearance_wait_time)); 78 base::TimeDelta::FromSeconds(g_bubble_appearance_wait_time));
79 } 79 }
80 80
81 void ExtensionMessageBubbleView::OnWidgetDestroying(views::Widget* widget) { 81 void ExtensionMessageBubbleView::OnWidgetDestroying(views::Widget* widget) {
82 // To catch Esc, we monitor destroy message. Unless the link has been clicked, 82 // To catch Esc, we monitor destroy message. Unless the link has been clicked,
83 // we assume Dismiss was the action taken. 83 // we assume Dismiss was the action taken.
84 if (!link_clicked_ && !action_taken_) { 84 if (!link_clicked_ && !action_taken_) {
85 bool closed_on_deactivation = close_reason() == CloseReason::DEACTIVATION; 85 bool closed_on_deactivation = close_reason() == CloseReason::DEACTIVATION;
86 controller_->OnBubbleDismiss(closed_on_deactivation); 86 delegate_->OnBubbleClosed(
87 closed_on_deactivation
88 ? ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_DEACTIVATION
89 : ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_USER_ACTION);
87 } 90 }
88 } 91 }
89 92
90 void ExtensionMessageBubbleView::set_bubble_appearance_wait_time_for_testing( 93 void ExtensionMessageBubbleView::set_bubble_appearance_wait_time_for_testing(
91 int time_in_seconds) { 94 int time_in_seconds) {
92 g_bubble_appearance_wait_time = time_in_seconds; 95 g_bubble_appearance_wait_time = time_in_seconds;
93 } 96 }
94 97
95 //////////////////////////////////////////////////////////////////////////////// 98 ////////////////////////////////////////////////////////////////////////////////
96 // ExtensionMessageBubbleView - private. 99 // ExtensionMessageBubbleView - private.
97 100
98 ExtensionMessageBubbleView::~ExtensionMessageBubbleView() {} 101 ExtensionMessageBubbleView::~ExtensionMessageBubbleView() {}
99 102
100 void ExtensionMessageBubbleView::ShowBubble() { 103 void ExtensionMessageBubbleView::ShowBubble() {
101 // Since we delay in showing the bubble, the applicable extension(s) may 104 // Since we delay in showing the bubble, the applicable extension(s) may
102 // have been removed. 105 // have been removed.
103 if (controller_->ShouldShow()) { 106 if (delegate_->ShouldShow()) {
104 controller_->OnShown(); 107 delegate_->OnBubbleShown();
105 GetWidget()->Show(); 108 GetWidget()->Show();
106 } else { 109 } else {
107 GetWidget()->Close(); 110 GetWidget()->Close();
108 } 111 }
109 } 112 }
110 113
111 void ExtensionMessageBubbleView::Init() { 114 void ExtensionMessageBubbleView::Init() {
112 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 115 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
113 116
114 views::GridLayout* layout = views::GridLayout::CreatePanel(this); 117 views::GridLayout* layout = views::GridLayout::CreatePanel(this);
115 layout->SetInsets(kInsetTop, kInsetLeft, 118 layout->SetInsets(kInsetTop, kInsetLeft,
116 kInsetBottomRight, kInsetBottomRight); 119 kInsetBottomRight, kInsetBottomRight);
117 SetLayoutManager(layout); 120 SetLayoutManager(layout);
118 121
119 ExtensionMessageBubbleController::Delegate* delegate =
120 controller_->delegate();
121
122 const int headline_column_set_id = 0; 122 const int headline_column_set_id = 0;
123 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id); 123 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id);
124 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 124 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
125 0, views::GridLayout::USE_PREF, 0, 0); 125 0, views::GridLayout::USE_PREF, 0, 0);
126 top_columns->AddPaddingColumn(1, 0); 126 top_columns->AddPaddingColumn(1, 0);
127 layout->StartRow(0, headline_column_set_id); 127 layout->StartRow(0, headline_column_set_id);
128 128
129 headline_ = new views::Label(delegate->GetTitle(), 129 headline_ = new views::Label(delegate_->GetHeadingText(),
130 rb.GetFontList(ui::ResourceBundle::MediumFont)); 130 rb.GetFontList(ui::ResourceBundle::MediumFont));
131 layout->AddView(headline_); 131 layout->AddView(headline_);
132 132
133 layout->AddPaddingRow(0, kHeadlineRowPadding); 133 layout->AddPaddingRow(0, kHeadlineRowPadding);
134 134
135 const int text_column_set_id = 1; 135 const int text_column_set_id = 1;
136 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); 136 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id);
137 upper_columns->AddColumn( 137 upper_columns->AddColumn(
138 views::GridLayout::LEADING, views::GridLayout::LEADING, 138 views::GridLayout::LEADING, views::GridLayout::LEADING,
139 0, views::GridLayout::USE_PREF, 0, 0); 139 0, views::GridLayout::USE_PREF, 0, 0);
140 layout->StartRow(0, text_column_set_id); 140 layout->StartRow(0, text_column_set_id);
141 141
142 views::Label* message = new views::Label(); 142 views::Label* message = new views::Label();
143 message->SetMultiLine(true); 143 message->SetMultiLine(true);
144 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); 144 message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
145 message->SetText(delegate->GetMessageBody( 145 message->SetText(
146 anchor_view_->id() == VIEW_ID_BROWSER_ACTION, 146 delegate_->GetBodyText(anchor_view_->id() == VIEW_ID_BROWSER_ACTION));
147 controller_->GetExtensionIdList().size()));
148 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( 147 message->SizeToFit(views::Widget::GetLocalizedContentsWidth(
149 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); 148 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS));
150 layout->AddView(message); 149 layout->AddView(message);
151 150
152 if (delegate->ShouldShowExtensionList()) { 151 base::string16 item_list_text = delegate_->GetItemListText();
152 if (!item_list_text.empty()) {
153 const int extension_list_column_set_id = 2; 153 const int extension_list_column_set_id = 2;
154 views::ColumnSet* middle_columns = 154 views::ColumnSet* middle_columns =
155 layout->AddColumnSet(extension_list_column_set_id); 155 layout->AddColumnSet(extension_list_column_set_id);
156 middle_columns->AddPaddingColumn(0, kExtensionListPadding); 156 middle_columns->AddPaddingColumn(0, kExtensionListPadding);
157 middle_columns->AddColumn( 157 middle_columns->AddColumn(
158 views::GridLayout::LEADING, views::GridLayout::CENTER, 158 views::GridLayout::LEADING, views::GridLayout::CENTER,
159 0, views::GridLayout::USE_PREF, 0, 0); 159 0, views::GridLayout::USE_PREF, 0, 0);
160 160
161 layout->StartRowWithPadding(0, extension_list_column_set_id, 161 layout->StartRowWithPadding(0, extension_list_column_set_id,
162 0, kHeadlineMessagePadding); 162 0, kHeadlineMessagePadding);
163 views::Label* extensions = new views::Label(); 163 views::Label* extensions = new views::Label();
164 extensions->SetMultiLine(true); 164 extensions->SetMultiLine(true);
165 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT); 165 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT);
166 166
167 extensions->SetText(controller_->GetExtensionListForDisplay()); 167 extensions->SetText(item_list_text);
168 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth( 168 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth(
169 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); 169 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS));
170 layout->AddView(extensions); 170 layout->AddView(extensions);
171 } 171 }
172 172
173 base::string16 action_button = delegate->GetActionButtonLabel(); 173 base::string16 action_button = delegate_->GetActionButtonText();
174 174
175 const int action_row_column_set_id = 3; 175 const int action_row_column_set_id = 3;
176 views::ColumnSet* bottom_columns = 176 views::ColumnSet* bottom_columns =
177 layout->AddColumnSet(action_row_column_set_id); 177 layout->AddColumnSet(action_row_column_set_id);
178 bottom_columns->AddColumn(views::GridLayout::LEADING, 178 bottom_columns->AddColumn(views::GridLayout::LEADING,
179 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); 179 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
180 bottom_columns->AddPaddingColumn(1, 0); 180 bottom_columns->AddPaddingColumn(1, 0);
181 bottom_columns->AddColumn(views::GridLayout::TRAILING, 181 bottom_columns->AddColumn(views::GridLayout::TRAILING,
182 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); 182 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
183 if (!action_button.empty()) { 183 if (!action_button.empty()) {
184 bottom_columns->AddColumn(views::GridLayout::TRAILING, 184 bottom_columns->AddColumn(views::GridLayout::TRAILING,
185 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); 185 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
186 } 186 }
187 layout->StartRowWithPadding(0, action_row_column_set_id, 187 layout->StartRowWithPadding(0, action_row_column_set_id,
188 0, kMessageBubblePadding); 188 0, kMessageBubblePadding);
189 189
190 learn_more_ = new views::Link(delegate->GetLearnMoreLabel()); 190 learn_more_ = new views::Link(delegate_->GetLearnMoreButtonText());
191 learn_more_->set_listener(this); 191 learn_more_->set_listener(this);
192 layout->AddView(learn_more_); 192 layout->AddView(learn_more_);
193 193
194 if (!action_button.empty()) { 194 if (!action_button.empty()) {
195 action_button_ = new views::LabelButton(this, action_button); 195 action_button_ = new views::LabelButton(this, action_button);
196 action_button_->SetStyle(views::Button::STYLE_BUTTON); 196 action_button_->SetStyle(views::Button::STYLE_BUTTON);
197 layout->AddView(action_button_); 197 layout->AddView(action_button_);
198 } 198 }
199 199
200 dismiss_button_ = new views::LabelButton(this, 200 dismiss_button_ =
201 delegate->GetDismissButtonLabel()); 201 new views::LabelButton(this, delegate_->GetDismissButtonText());
202 dismiss_button_->SetStyle(views::Button::STYLE_BUTTON); 202 dismiss_button_->SetStyle(views::Button::STYLE_BUTTON);
203 layout->AddView(dismiss_button_); 203 layout->AddView(dismiss_button_);
204 } 204 }
205 205
206 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender, 206 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender,
207 const ui::Event& event) { 207 const ui::Event& event) {
208 action_taken_ = true; 208 action_taken_ = true;
209 ToolbarActionsBarBubbleDelegate::CloseAction close_action;
209 if (sender == action_button_) { 210 if (sender == action_button_) {
210 controller_->OnBubbleAction(); 211 close_action = ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE;
211 } else { 212 } else {
212 DCHECK_EQ(dismiss_button_, sender); 213 DCHECK_EQ(dismiss_button_, sender);
213 controller_->OnBubbleDismiss(false); // Not closed by deactivation. 214 close_action = ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_USER_ACTION;
214 } 215 }
216 delegate_->OnBubbleClosed(close_action);
215 GetWidget()->Close(); 217 GetWidget()->Close();
216 } 218 }
217 219
218 void ExtensionMessageBubbleView::LinkClicked(views::Link* source, 220 void ExtensionMessageBubbleView::LinkClicked(views::Link* source,
219 int event_flags) { 221 int event_flags) {
220 DCHECK_EQ(learn_more_, source); 222 DCHECK_EQ(learn_more_, source);
221 link_clicked_ = true; 223 link_clicked_ = true;
222 controller_->OnLinkClicked(); 224 delegate_->OnBubbleClosed(ToolbarActionsBarBubbleDelegate::CLOSE_LEARN_MORE);
223 GetWidget()->Close(); 225 GetWidget()->Close();
224 } 226 }
225 227
226 void ExtensionMessageBubbleView::GetAccessibleState( 228 void ExtensionMessageBubbleView::GetAccessibleState(
227 ui::AXViewState* state) { 229 ui::AXViewState* state) {
228 state->role = ui::AX_ROLE_ALERT; 230 state->role = ui::AX_ROLE_ALERT;
229 } 231 }
230 232
231 void ExtensionMessageBubbleView::ViewHierarchyChanged( 233 void ExtensionMessageBubbleView::ViewHierarchyChanged(
232 const ViewHierarchyChangedDetails& details) { 234 const ViewHierarchyChangedDetails& details) {
233 if (details.is_add && details.child == this) 235 if (details.is_add && details.child == this)
234 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); 236 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
235 } 237 }
236 238
237 } // namespace extensions 239 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698