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

Side by Side Diff: chrome/browser/ui/views/location_bar/page_action_image_view.cc

Issue 431173002: Create ExtensionActionView class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge conflict Created 6 years, 4 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/location_bar/page_action_image_view.h" 5 #include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/api/commands/command_service.h"
9 #include "chrome/browser/extensions/extension_action.h" 8 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_action_icon_factory.h"
11 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_context_menu_model.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/extensions/location_bar_controller.h"
15 #include "chrome/browser/extensions/tab_helper.h"
16 #include "chrome/browser/platform_util.h" 9 #include "chrome/browser/platform_util.h"
17 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/sessions/session_id.h" 11 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_list.h"
20 #include "chrome/browser/ui/extensions/accelerator_priority.h"
21 #include "chrome/browser/ui/views/frame/browser_view.h"
22 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 12 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
23 #include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
24 #include "extensions/browser/extension_registry.h" 13 #include "extensions/browser/extension_registry.h"
25 #include "extensions/common/extension.h"
26 #include "ui/accessibility/ax_view_state.h" 14 #include "ui/accessibility/ax_view_state.h"
27 #include "ui/events/event.h" 15 #include "ui/events/event.h"
28 #include "ui/gfx/canvas.h" 16 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/image/image.h" 17 #include "ui/gfx/image/image.h"
30 #include "ui/views/controls/menu/menu_runner.h"
31
32 using content::WebContents;
33 using extensions::LocationBarController;
34 using extensions::Extension;
35 18
36 // static 19 // static
37 const char PageActionImageView::kViewClassName[] = "PageActionImageView"; 20 const char PageActionImageView::kViewClassName[] = "PageActionImageView";
38 21
39 PageActionImageView::PageActionImageView(LocationBarView* owner, 22 PageActionImageView::PageActionImageView(LocationBarView* owner,
40 ExtensionAction* page_action, 23 ExtensionAction* page_action,
41 Browser* browser) 24 Browser* browser)
42 : owner_(owner), 25 : view_controller_(new ExtensionActionViewController(
43 page_action_(page_action), 26 extensions::ExtensionRegistry::Get(browser->profile())->
44 browser_(browser), 27 enabled_extensions().GetByID(page_action->extension_id()),
45 current_tab_id_(-1), 28 browser,
46 preview_enabled_(false), 29 page_action,
47 popup_(NULL) { 30 this)),
48 const Extension* extension = extensions::ExtensionRegistry::Get( 31 owner_(owner),
49 owner_->profile())->enabled_extensions().GetByID( 32 preview_enabled_(false) {
50 page_action->extension_id()); 33 // There should be an associated focus manager so that we can safely register
51 DCHECK(extension); 34 // accelerators for commands.
52 35 DCHECK(GetFocusManagerForAccelerator());
53 icon_factory_.reset(
54 new ExtensionActionIconFactory(
55 owner_->profile(), extension, page_action, this));
56
57 SetAccessibilityFocusable(true); 36 SetAccessibilityFocusable(true);
58 set_context_menu_controller(this); 37 view_controller_->RegisterCommand();
59 38 set_context_menu_controller(view_controller_.get());
60 extensions::CommandService* command_service =
61 extensions::CommandService::Get(browser_->profile());
62 extensions::Command page_action_command;
63 if (command_service->GetPageActionCommand(
64 extension->id(),
65 extensions::CommandService::ACTIVE_ONLY,
66 &page_action_command,
67 NULL)) {
68 page_action_keybinding_.reset(
69 new ui::Accelerator(page_action_command.accelerator()));
70 owner_->GetFocusManager()->RegisterAccelerator(
71 *page_action_keybinding_.get(),
72 GetAcceleratorPriority(page_action_command.accelerator(), extension),
73 this);
74 }
75 } 39 }
76 40
77 PageActionImageView::~PageActionImageView() { 41 PageActionImageView::~PageActionImageView() {
78 if (owner_->GetFocusManager()) {
79 if (page_action_keybinding_.get()) {
80 owner_->GetFocusManager()->UnregisterAccelerator(
81 *page_action_keybinding_.get(), this);
82 }
83 }
84
85 if (popup_)
86 popup_->GetWidget()->RemoveObserver(this);
87 HidePopup();
88 }
89
90 void PageActionImageView::ExecuteAction(
91 ExtensionPopup::ShowAction show_action) {
92 WebContents* web_contents = owner_->GetWebContents();
93 if (!web_contents)
94 return;
95
96 extensions::TabHelper* extensions_tab_helper =
97 extensions::TabHelper::FromWebContents(web_contents);
98 LocationBarController* controller =
99 extensions_tab_helper->location_bar_controller();
100
101 switch (controller->OnClicked(page_action_)) {
102 case LocationBarController::ACTION_NONE:
103 break;
104
105 case LocationBarController::ACTION_SHOW_POPUP:
106 ShowPopupWithURL(page_action_->GetPopupUrl(current_tab_id_), show_action);
107 break;
108
109 case LocationBarController::ACTION_SHOW_CONTEXT_MENU:
110 // We are never passing OnClicked a right-click button, so assume that
111 // we're never going to be asked to show a context menu.
112 // TODO(kalman): if this changes, update this class to pass the real
113 // mouse button through to the LocationBarController.
114 NOTREACHED();
115 break;
116 }
117 } 42 }
118 43
119 const char* PageActionImageView::GetClassName() const { 44 const char* PageActionImageView::GetClassName() const {
120 return kViewClassName; 45 return kViewClassName;
121 } 46 }
122 47
123 void PageActionImageView::GetAccessibleState(ui::AXViewState* state) { 48 void PageActionImageView::GetAccessibleState(ui::AXViewState* state) {
124 state->role = ui::AX_ROLE_BUTTON; 49 state->role = ui::AX_ROLE_BUTTON;
125 state->name = base::UTF8ToUTF16(tooltip_); 50 state->name = base::UTF8ToUTF16(tooltip_);
126 } 51 }
127 52
128 bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) { 53 bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) {
129 // We want to show the bubble on mouse release; that is the standard behavior 54 // We want to show the bubble on mouse release; that is the standard behavior
130 // for buttons. (Also, triggering on mouse press causes bugs like 55 // for buttons. (Also, triggering on mouse press causes bugs like
131 // http://crbug.com/33155.) 56 // http://crbug.com/33155.)
132 return true; 57 return true;
133 } 58 }
134 59
135 void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) { 60 void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) {
136 if (!HitTestPoint(event.location())) 61 if (!HitTestPoint(event.location()))
137 return; 62 return;
138 63
139 if (event.IsRightMouseButton()) { 64 if (event.IsRightMouseButton()) {
140 // Don't show a menu here, its handled in View::ProcessMouseReleased. We 65 // Don't show a menu here, its handled in View::ProcessMouseReleased. We
141 // show the context menu by way of being the ContextMenuController. 66 // show the context menu by way of being the ContextMenuController.
142 return; 67 return;
143 } 68 }
144 69
145 ExecuteAction(ExtensionPopup::SHOW); 70 view_controller_->ExecuteActionByUser();
146 } 71 }
147 72
148 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) { 73 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) {
149 if (event.key_code() == ui::VKEY_SPACE || 74 if (event.key_code() == ui::VKEY_SPACE ||
150 event.key_code() == ui::VKEY_RETURN) { 75 event.key_code() == ui::VKEY_RETURN) {
151 ExecuteAction(ExtensionPopup::SHOW); 76 view_controller_->ExecuteActionByUser();
152 return true; 77 return true;
153 } 78 }
154 return false; 79 return false;
155 } 80 }
156 81
157 void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) { 82 void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) {
158 if (event->type() == ui::ET_GESTURE_TAP) { 83 if (event->type() == ui::ET_GESTURE_TAP) {
159 ExecuteAction(ExtensionPopup::SHOW); 84 view_controller_->ExecuteActionByUser();
160 event->SetHandled(); 85 event->SetHandled();
161 } 86 }
162 } 87 }
163 88
164 void PageActionImageView::ShowContextMenuForView( 89 void PageActionImageView::UpdateVisibility(content::WebContents* contents) {
165 View* source, 90 int tab_id = view_controller_->GetCurrentTabId();
166 const gfx::Point& point,
167 ui::MenuSourceType source_type) {
168 const Extension* extension = extensions::ExtensionRegistry::Get(
169 owner_->profile())->enabled_extensions().GetByID(
170 page_action()->extension_id());
171 if (!extension->ShowConfigureContextMenus())
172 return;
173
174 scoped_refptr<ExtensionContextMenuModel> context_menu_model(
175 new ExtensionContextMenuModel(extension, browser_, this));
176 menu_runner_.reset(new views::MenuRunner(
177 context_menu_model.get(),
178 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
179 gfx::Point screen_loc;
180 views::View::ConvertPointToScreen(this, &screen_loc);
181 if (menu_runner_->RunMenuAt(GetWidget(),
182 NULL,
183 gfx::Rect(screen_loc, size()),
184 views::MENU_ANCHOR_TOPLEFT,
185 source_type) == views::MenuRunner::MENU_DELETED) {
186 return;
187 }
188 }
189
190 bool PageActionImageView::AcceleratorPressed(
191 const ui::Accelerator& accelerator) {
192 DCHECK(visible()); // Should not have happened due to CanHandleAccelerator.
193
194 const std::string extension_id = page_action()->extension_id();
195 const ui::AcceleratorManager::HandlerPriority priority =
196 GetAcceleratorPriorityById(accelerator, extension_id, owner_->profile());
197 // Normal priority shortcuts must be handled via standard browser commands
198 // to be processed at the proper time.
199 if (priority == ui::AcceleratorManager::kHighPriority)
200 ExecuteAction(ExtensionPopup::SHOW);
201 return priority == ui::AcceleratorManager::kHighPriority;
202 }
203
204 bool PageActionImageView::CanHandleAccelerators() const {
205 // While visible, we don't handle accelerators and while so we also don't
206 // count as a priority accelerator handler.
207 return visible();
208 }
209
210 void PageActionImageView::UpdateVisibility(WebContents* contents,
211 const GURL& url) {
212 // Save this off so we can pass it back to the extension when the action gets
213 // executed. See PageActionImageView::OnMousePressed.
214 current_tab_id_ =
215 contents ? extensions::ExtensionTabUtil::GetTabId(contents) : -1;
216 current_url_ = url;
217 91
218 if (!contents || 92 if (!contents ||
219 (!preview_enabled_ && !page_action_->GetIsVisible(current_tab_id_))) { 93 tab_id == -1 ||
94 (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) {
220 SetVisible(false); 95 SetVisible(false);
221 return; 96 return;
222 } 97 }
223 98
224 // Set the tooltip. 99 // Set the tooltip.
225 tooltip_ = page_action_->GetTitle(current_tab_id_); 100 tooltip_ = extension_action()->GetTitle(tab_id);
226 SetTooltipText(base::UTF8ToUTF16(tooltip_)); 101 SetTooltipText(base::UTF8ToUTF16(tooltip_));
227 102
228 // Set the image. 103 // Set the image.
229 gfx::Image icon = icon_factory_->GetIcon(current_tab_id_); 104 gfx::Image icon = view_controller_->GetIcon(tab_id);
230 if (!icon.IsEmpty()) 105 if (!icon.IsEmpty())
231 SetImage(*icon.ToImageSkia()); 106 SetImage(*icon.ToImageSkia());
232 107
233 SetVisible(true); 108 SetVisible(true);
234 } 109 }
235 110
236 void PageActionImageView::InspectPopup() { 111 void PageActionImageView::PaintChildren(gfx::Canvas* canvas,
237 ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT); 112 const views::CullSet& cull_set) {
238 } 113 View::PaintChildren(canvas, cull_set);
239 114 int tab_id = view_controller_->GetCurrentTabId();
240 void PageActionImageView::OnWidgetDestroying(views::Widget* widget) { 115 if (tab_id >= 0) {
241 DCHECK_EQ(popup_->GetWidget(), widget); 116 view_controller_->extension_action()->PaintBadge(
242 popup_->GetWidget()->RemoveObserver(this); 117 canvas, GetLocalBounds(), tab_id);
243 popup_ = NULL; 118 }
244 } 119 }
245 120
246 void PageActionImageView::OnIconUpdated() { 121 void PageActionImageView::OnIconUpdated() {
247 WebContents* web_contents = owner_->GetWebContents(); 122 UpdateVisibility(GetCurrentWebContents());
248 if (web_contents)
249 UpdateVisibility(web_contents, current_url_);
250 } 123 }
251 124
252 void PageActionImageView::PaintChildren(gfx::Canvas* canvas, 125 views::View* PageActionImageView::GetAsView() {
253 const views::CullSet& cull_set) { 126 return this;
254 View::PaintChildren(canvas, cull_set);
255 if (current_tab_id_ >= 0)
256 page_action_->PaintBadge(canvas, GetLocalBounds(), current_tab_id_);
257 } 127 }
258 128
259 void PageActionImageView::ShowPopupWithURL( 129 bool PageActionImageView::IsShownInMenu() {
260 const GURL& popup_url, 130 return false;
261 ExtensionPopup::ShowAction show_action) {
262 bool popup_showing = popup_ != NULL;
263
264 // Always hide the current popup. Only one popup at a time.
265 HidePopup();
266
267 // If we were already showing, then treat this click as a dismiss.
268 if (popup_showing)
269 return;
270
271 views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
272 views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
273
274 popup_ = ExtensionPopup::ShowPopup(popup_url, browser_, this, arrow,
275 show_action);
276 popup_->GetWidget()->AddObserver(this);
277 } 131 }
278 132
279 void PageActionImageView::HidePopup() { 133 views::FocusManager* PageActionImageView::GetFocusManagerForAccelerator() {
280 if (popup_) 134 return owner_->GetFocusManager();
281 popup_->GetWidget()->Close();
282 } 135 }
136
137 views::Widget* PageActionImageView::GetParentForContextMenu() {
138 return GetWidget();
139 }
140
141 views::View* PageActionImageView::GetReferenceViewForPopup() {
142 return this;
143 }
144
145 content::WebContents* PageActionImageView::GetCurrentWebContents() {
146 return owner_->GetWebContents();
147 }
148
149 void PageActionImageView::HideActivePopup() {
150 // The only popup that will be active is this popup.
151 view_controller_->HidePopup();
152 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698