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

Side by Side Diff: chrome/browser/views/browser_actions_container.cc

Issue 3073018: Merge 53841 - Cleanup: Remove pointless GetInsets() override. Simplify |cont... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/472/src/
Patch Set: Created 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/views/browser_actions_container.h" 5 #include "chrome/browser/views/browser_actions_container.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "app/slide_animation.h" 9 #include "app/slide_animation.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 // The margin above the chevron. 73 // The margin above the chevron.
74 static const int kChevronTopMargin = 9; 74 static const int kChevronTopMargin = 9;
75 75
76 // The margin to the right of the chevron. 76 // The margin to the right of the chevron.
77 static const int kChevronRightMargin = 4; 77 static const int kChevronRightMargin = 4;
78 78
79 // Width for the resize area. 79 // Width for the resize area.
80 static const int kResizeAreaWidth = 4; 80 static const int kResizeAreaWidth = 4;
81 81
82 // Width of the drop indicator.
83 static const int kDropIndicatorWidth = 2;
84
85 // Color of the drop indicator.
86 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
87
88 // The x offset for the drop indicator (how much we shift it by). 82 // The x offset for the drop indicator (how much we shift it by).
89 static const int kDropIndicatorOffsetLtr = 3; 83 static const int kDropIndicatorOffsetLtr = 3;
90 static const int kDropIndicatorOffsetRtl = 9; 84 static const int kDropIndicatorOffsetRtl = 9;
91 85
92 } // namespace. 86 } // namespace.
93 87
94 // Static. 88 // Static.
95 bool BrowserActionsContainer::disable_animations_during_testing_ = false; 89 bool BrowserActionsContainer::disable_animations_during_testing_ = false;
96 90
97 //////////////////////////////////////////////////////////////////////////////// 91 ////////////////////////////////////////////////////////////////////////////////
98 // BrowserActionButton 92 // BrowserActionButton
99 93
100 BrowserActionButton::BrowserActionButton(Extension* extension, 94 BrowserActionButton::BrowserActionButton(Extension* extension,
101 BrowserActionsContainer* panel) 95 BrowserActionsContainer* panel)
102 : ALLOW_THIS_IN_INITIALIZER_LIST(MenuButton(this, L"", NULL, false)), 96 : ALLOW_THIS_IN_INITIALIZER_LIST(
97 MenuButton(this, std::wstring(), NULL, false)),
103 browser_action_(extension->browser_action()), 98 browser_action_(extension->browser_action()),
104 extension_(extension), 99 extension_(extension),
105 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)), 100 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
106 showing_context_menu_(false), 101 showing_context_menu_(false),
107 panel_(panel) { 102 panel_(panel) {
108 set_alignment(TextButton::ALIGN_CENTER); 103 set_alignment(TextButton::ALIGN_CENTER);
109 104
110 // No UpdateState() here because View hierarchy not setup yet. Our parent 105 // No UpdateState() here because View hierarchy not setup yet. Our parent
111 // should call UpdateState() after creation. 106 // should call UpdateState() after creation.
112 107
(...skipping 19 matching lines...) Expand all
132 127
133 void BrowserActionButton::Destroy() { 128 void BrowserActionButton::Destroy() {
134 if (showing_context_menu_) { 129 if (showing_context_menu_) {
135 context_menu_menu_->CancelMenu(); 130 context_menu_menu_->CancelMenu();
136 MessageLoop::current()->DeleteSoon(FROM_HERE, this); 131 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
137 } else { 132 } else {
138 delete this; 133 delete this;
139 } 134 }
140 } 135 }
141 136
142 gfx::Insets BrowserActionButton::GetInsets() const { 137 void BrowserActionButton::ButtonPressed(views::Button* sender,
143 static gfx::Insets zero_inset; 138 const views::Event& event) {
144 return zero_inset; 139 panel_->OnBrowserActionExecuted(this, false);
145 } 140 }
146 141
147 void BrowserActionButton::ButtonPressed(views::Button* sender, 142 void BrowserActionButton::OnImageLoaded(SkBitmap* image,
148 const views::Event& event) { 143 ExtensionResource resource,
149 panel_->OnBrowserActionExecuted(this, false); // inspect_with_devtools 144 int index) {
150 }
151
152 void BrowserActionButton::OnImageLoaded(
153 SkBitmap* image, ExtensionResource resource, int index) {
154 if (image) 145 if (image)
155 default_icon_ = *image; 146 default_icon_ = *image;
156 147
157 // Call back to UpdateState() because a more specific icon might have been set 148 // Call back to UpdateState() because a more specific icon might have been set
158 // while the load was outstanding. 149 // while the load was outstanding.
159 UpdateState(); 150 UpdateState();
160 } 151 }
161 152
162 void BrowserActionButton::UpdateState() { 153 void BrowserActionButton::UpdateState() {
163 int tab_id = panel_->GetCurrentTabId(); 154 int tab_id = panel_->GetCurrentTabId();
(...skipping 11 matching lines...) Expand all
175 if (name.empty()) 166 if (name.empty())
176 name = UTF8ToWide(extension()->name()); 167 name = UTF8ToWide(extension()->name());
177 SetTooltipText(name); 168 SetTooltipText(name);
178 SetAccessibleName(name); 169 SetAccessibleName(name);
179 GetParent()->SchedulePaint(); 170 GetParent()->SchedulePaint();
180 } 171 }
181 172
182 void BrowserActionButton::Observe(NotificationType type, 173 void BrowserActionButton::Observe(NotificationType type,
183 const NotificationSource& source, 174 const NotificationSource& source,
184 const NotificationDetails& details) { 175 const NotificationDetails& details) {
185 if (type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED) { 176 DCHECK(type == NotificationType::EXTENSION_BROWSER_ACTION_UPDATED);
186 UpdateState(); 177 UpdateState();
187 // The browser action may have become visible/hidden so we need to make 178 // The browser action may have become visible/hidden so we need to make
188 // sure the state gets updated. 179 // sure the state gets updated.
189 panel_->OnBrowserActionVisibilityChanged(); 180 panel_->OnBrowserActionVisibilityChanged();
190 } else {
191 NOTREACHED() << L"Received unexpected notification";
192 }
193 } 181 }
194 182
195 bool BrowserActionButton::IsPopup() { 183 bool BrowserActionButton::IsPopup() {
196 int tab_id = panel_->GetCurrentTabId(); 184 int tab_id = panel_->GetCurrentTabId();
197 if (tab_id < 0) { 185 DCHECK_GE(tab_id, 0);
198 NOTREACHED() << "Button is not on a specific tab.";
199 return false;
200 }
201 return browser_action_->HasPopup(tab_id); 186 return browser_action_->HasPopup(tab_id);
202 } 187 }
203 188
204 GURL BrowserActionButton::GetPopupUrl() { 189 GURL BrowserActionButton::GetPopupUrl() {
205 int tab_id = panel_->GetCurrentTabId(); 190 int tab_id = panel_->GetCurrentTabId();
206 if (tab_id < 0) { 191 DCHECK_GE(tab_id, 0);
207 NOTREACHED() << "Button is not on a specific tab.";
208 GURL empty_url;
209 return empty_url;
210 }
211 return browser_action_->GetPopupUrl(tab_id); 192 return browser_action_->GetPopupUrl(tab_id);
212 } 193 }
213 194
214 bool BrowserActionButton::Activate() { 195 bool BrowserActionButton::Activate() {
215 if (IsPopup()) { 196 if (!IsPopup())
216 panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|. 197 return true;
217 198
218 // TODO(erikkay): Run a nested modal loop while the mouse is down to 199 panel_->OnBrowserActionExecuted(this, false); // |inspect_with_devtools|.
219 // enable menu-like drag-select behavior.
220 200
221 // The return value of this method is returned via OnMousePressed. 201 // TODO(erikkay): Run a nested modal loop while the mouse is down to
222 // We need to return false here since we're handing off focus to another 202 // enable menu-like drag-select behavior.
223 // widget/view, and true will grab it right back and try to send events 203
224 // to us. 204 // The return value of this method is returned via OnMousePressed.
225 return false; 205 // We need to return false here since we're handing off focus to another
226 } 206 // widget/view, and true will grab it right back and try to send events
227 return true; 207 // to us.
208 return false;
228 } 209 }
229 210
230 bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) { 211 bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) {
231 if (e.IsRightMouseButton()) { 212 if (!e.IsRightMouseButton()) {
232 // Get the top left point of this button in screen coordinates. 213 return IsPopup() ?
233 gfx::Point point = gfx::Point(0, 0); 214 MenuButton::OnMousePressed(e) : TextButton::OnMousePressed(e);
234 ConvertPointToScreen(this, &point); 215 }
235 216
236 // Make the menu appear below the button. 217 // Get the top left point of this button in screen coordinates.
237 point.Offset(0, height()); 218 gfx::Point point = gfx::Point(0, 0);
219 ConvertPointToScreen(this, &point);
238 220
239 ShowContextMenu(point, true); 221 // Make the menu appear below the button.
240 return false; 222 point.Offset(0, height());
241 } else if (IsPopup()) { 223
242 return MenuButton::OnMousePressed(e); 224 ShowContextMenu(point, true);
243 } 225 return false;
244 return TextButton::OnMousePressed(e);
245 } 226 }
246 227
247 void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e, 228 void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e,
248 bool canceled) { 229 bool canceled) {
249 if (IsPopup() || showing_context_menu_) { 230 if (IsPopup() || showing_context_menu_) {
250 // TODO(erikkay) this never actually gets called (probably because of the 231 // TODO(erikkay) this never actually gets called (probably because of the
251 // loss of focus). 232 // loss of focus).
252 MenuButton::OnMouseReleased(e, canceled); 233 MenuButton::OnMouseReleased(e, canceled);
253 } else { 234 } else {
254 TextButton::OnMouseReleased(e, canceled); 235 TextButton::OnMouseReleased(e, canceled);
255 } 236 }
256 } 237 }
257 238
258 bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) { 239 bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) {
259 if (IsPopup()) 240 return IsPopup() ?
260 return MenuButton::OnKeyReleased(e); 241 MenuButton::OnKeyReleased(e) : TextButton::OnKeyReleased(e);
261 return TextButton::OnKeyReleased(e);
262 } 242 }
263 243
264 void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) { 244 void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) {
265 if (IsPopup() || showing_context_menu_) 245 if (IsPopup() || showing_context_menu_)
266 MenuButton::OnMouseExited(e); 246 MenuButton::OnMouseExited(e);
267 else 247 else
268 TextButton::OnMouseExited(e); 248 TextButton::OnMouseExited(e);
269 } 249 }
270 250
271 void BrowserActionButton::ShowContextMenu(const gfx::Point& p, 251 void BrowserActionButton::ShowContextMenu(const gfx::Point& p,
272 bool is_mouse_gesture) { 252 bool is_mouse_gesture) {
273 showing_context_menu_ = true; 253 showing_context_menu_ = true;
274 SetButtonPushed(); 254 SetButtonPushed();
275 255
276 // Reconstructs the menu every time because the menu's contents are dynamic. 256 // Reconstructs the menu every time because the menu's contents are dynamic.
277 context_menu_contents_ = new ExtensionContextMenuModel( 257 context_menu_contents_ =
278 extension(), panel_->browser(), panel_); 258 new ExtensionContextMenuModel(extension(), panel_->browser(), panel_);
279 context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get())); 259 context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
280 context_menu_menu_->RunContextMenuAt(p); 260 context_menu_menu_->RunContextMenuAt(p);
281 261
282 SetButtonNotPushed(); 262 SetButtonNotPushed();
283 showing_context_menu_ = false; 263 showing_context_menu_ = false;
284 } 264 }
285 265
286 void BrowserActionButton::SetButtonPushed() { 266 void BrowserActionButton::SetButtonPushed() {
287 SetState(views::CustomButton::BS_PUSHED); 267 SetState(views::CustomButton::BS_PUSHED);
288 menu_visible_ = true; 268 menu_visible_ = true;
(...skipping 27 matching lines...) Expand all
316 button_->Destroy(); 296 button_->Destroy();
317 } 297 }
318 298
319 gfx::Canvas* BrowserActionView::GetIconWithBadge() { 299 gfx::Canvas* BrowserActionView::GetIconWithBadge() {
320 int tab_id = panel_->GetCurrentTabId(); 300 int tab_id = panel_->GetCurrentTabId();
321 301
322 SkBitmap icon = button_->extension()->browser_action()->GetIcon(tab_id); 302 SkBitmap icon = button_->extension()->browser_action()->GetIcon(tab_id);
323 if (icon.isNull()) 303 if (icon.isNull())
324 icon = button_->default_icon(); 304 icon = button_->default_icon();
325 305
326 gfx::Canvas* canvas = 306 gfx::Canvas* canvas = new gfx::CanvasSkia(icon.width(), icon.height(), false);
327 new gfx::CanvasSkia(icon.width(), icon.height(), false);
328 canvas->DrawBitmapInt(icon, 0, 0); 307 canvas->DrawBitmapInt(icon, 0, 0);
329 308
330 if (tab_id >= 0) { 309 if (tab_id >= 0) {
331 gfx::Rect bounds = 310 gfx::Rect bounds(icon.width(), icon.height() + kControlVertOffset);
332 gfx::Rect(icon.width(), icon.height() + kControlVertOffset); 311 button_->extension()->browser_action()->PaintBadge(canvas, bounds, tab_id);
333 button_->extension()->browser_action()->PaintBadge(canvas,
334 bounds, tab_id);
335 } 312 }
336 313
337 return canvas; 314 return canvas;
338 } 315 }
339 316
340 bool BrowserActionView::GetAccessibleRole(AccessibilityTypes::Role* role) { 317 bool BrowserActionView::GetAccessibleRole(AccessibilityTypes::Role* role) {
341 DCHECK(role); 318 DCHECK(role);
342 *role = AccessibilityTypes::ROLE_GROUPING; 319 *role = AccessibilityTypes::ROLE_GROUPING;
343 return true; 320 return true;
344 } 321 }
345 322
346 void BrowserActionView::Layout() { 323 void BrowserActionView::Layout() {
347 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize); 324 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize);
348 } 325 }
349 326
350 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { 327 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) {
351 View::PaintChildren(canvas); 328 View::PaintChildren(canvas);
352 ExtensionAction* action = button()->browser_action(); 329 ExtensionAction* action = button()->browser_action();
353 int tab_id = panel_->GetCurrentTabId(); 330 int tab_id = panel_->GetCurrentTabId();
354 if (tab_id < 0) 331 if (tab_id >= 0)
355 return; 332 action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id);
356
357 action->PaintBadge(canvas, gfx::Rect(width(), height()), tab_id);
358 } 333 }
359 334
360 //////////////////////////////////////////////////////////////////////////////// 335 ////////////////////////////////////////////////////////////////////////////////
361 // BrowserActionsContainer 336 // BrowserActionsContainer
362 337
363 BrowserActionsContainer::BrowserActionsContainer( 338 BrowserActionsContainer::BrowserActionsContainer(Browser* browser,
364 Browser* browser, View* owner_view) 339 View* owner_view)
365 : profile_(browser->profile()), 340 : profile_(browser->profile()),
366 browser_(browser), 341 browser_(browser),
367 owner_view_(owner_view), 342 owner_view_(owner_view),
368 popup_(NULL), 343 popup_(NULL),
369 popup_button_(NULL), 344 popup_button_(NULL),
370 model_(NULL), 345 model_(NULL),
371 chevron_(NULL), 346 chevron_(NULL),
372 overflow_menu_(NULL), 347 overflow_menu_(NULL),
373 suppress_chevron_(false), 348 suppress_chevron_(false),
374 resize_amount_(0), 349 resize_amount_(0),
375 animation_target_size_(0), 350 animation_target_size_(0),
376 drop_indicator_position_(-1), 351 drop_indicator_position_(-1),
377 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 352 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
378 ALLOW_THIS_IN_INITIALIZER_LIST(show_menu_task_factory_(this)) { 353 ALLOW_THIS_IN_INITIALIZER_LIST(show_menu_task_factory_(this)) {
379 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); 354 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
380 355
381 if (profile_->GetExtensionsService()) { 356 if (profile_->GetExtensionsService()) {
382 model_ = profile_->GetExtensionsService()->toolbar_model(); 357 model_ = profile_->GetExtensionsService()->toolbar_model();
383 model_->AddObserver(this); 358 model_->AddObserver(this);
384 } 359 }
360
385 resize_animation_.reset(new SlideAnimation(this)); 361 resize_animation_.reset(new SlideAnimation(this));
386 resize_area_ = new views::ResizeArea(this); 362 resize_area_ = new views::ResizeArea(this);
387 resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR)); 363 resize_area_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SEPARATOR));
388 AddChildView(resize_area_); 364 AddChildView(resize_area_);
389 365
390 // TODO(glen): Come up with a new bitmap for the chevron. 366 // TODO(glen): Come up with a new bitmap for the chevron.
391 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 367 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
392 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS); 368 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
393 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); 369 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
394 chevron_->SetVisible(false); 370 chevron_->SetVisible(false);
395 chevron_->SetIcon(*chevron_image); 371 chevron_->SetIcon(*chevron_image);
396 chevron_->SetAccessibleName( 372 chevron_->SetAccessibleName(
397 l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON)); 373 l10n_util::GetString(IDS_ACCNAME_EXTENSIONS_CHEVRON));
398 // Chevron contains >> that should point left in LTR locales. 374 // Chevron contains >> that should point left in LTR locales.
399 chevron_->EnableCanvasFlippingForRTLUI(true); 375 chevron_->EnableCanvasFlippingForRTLUI(true);
400 AddChildView(chevron_); 376 AddChildView(chevron_);
401 377
402 if (!profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) { 378 if (model_ &&
379 !profile_->GetPrefs()->HasPrefPath(prefs::kExtensionToolbarSize)) {
403 // Migration code to the new VisibleIconCount pref. 380 // Migration code to the new VisibleIconCount pref.
404 // TODO(mpcomplete): remove this after users are upgraded to 5.0. 381 // TODO(mpcomplete): remove this after users are upgraded to 5.0.
405 int predefined_width = 382 int predefined_width =
406 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); 383 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth);
407 if (predefined_width != 0) { 384 if (predefined_width != 0) {
408 int icon_width = (kButtonSize + kBrowserActionButtonPadding); 385 model_->SetVisibleIconCount((predefined_width - WidthOfNonIconArea()) /
409 if (model_) { 386 (kButtonSize + kBrowserActionButtonPadding));
410 model_->SetVisibleIconCount(
411 (predefined_width - WidthOfNonIconArea()) / icon_width);
412 }
413 } 387 }
414 } 388 }
415
416 if (model_ && model_->extensions_initialized()) 389 if (model_ && model_->extensions_initialized())
417 SetContainerWidth(); 390 SetContainerWidth();
418 391
419 SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS)); 392 SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS));
420 } 393 }
421 394
422 BrowserActionsContainer::~BrowserActionsContainer() { 395 BrowserActionsContainer::~BrowserActionsContainer() {
423 if (model_) 396 if (model_)
424 model_->RemoveObserver(this); 397 model_->RemoveObserver(this);
425 StopShowFolderDropMenuTimer(); 398 StopShowFolderDropMenuTimer();
426 HidePopup(); 399 HidePopup();
427 DeleteBrowserActionViews(); 400 DeleteBrowserActionViews();
428 } 401 }
429 402
430 // Static. 403 // Static.
431 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) { 404 void BrowserActionsContainer::RegisterUserPrefs(PrefService* prefs) {
432 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0); 405 prefs->RegisterIntegerPref(prefs::kBrowserActionContainerWidth, 0);
433 } 406 }
434 407
435 int BrowserActionsContainer::GetCurrentTabId() const { 408 int BrowserActionsContainer::GetCurrentTabId() const {
436 TabContents* tab_contents = browser_->GetSelectedTabContents(); 409 TabContents* tab_contents = browser_->GetSelectedTabContents();
437 if (!tab_contents) 410 return tab_contents ? tab_contents->controller().session_id().id() : -1;
438 return -1;
439
440 return tab_contents->controller().session_id().id();
441 } 411 }
442 412
443 BrowserActionView* BrowserActionsContainer::GetBrowserActionView( 413 BrowserActionView* BrowserActionsContainer::GetBrowserActionView(
444 ExtensionAction* action) { 414 ExtensionAction* action) {
445 for (BrowserActionViews::iterator iter = 415 for (BrowserActionViews::iterator iter = browser_action_views_.begin();
446 browser_action_views_.begin(); iter != browser_action_views_.end(); 416 iter != browser_action_views_.end(); ++iter) {
447 ++iter) {
448 if ((*iter)->button()->browser_action() == action) 417 if ((*iter)->button()->browser_action() == action)
449 return *iter; 418 return *iter;
450 } 419 }
451
452 return NULL; 420 return NULL;
453 } 421 }
454 422
455 void BrowserActionsContainer::RefreshBrowserActionViews() { 423 void BrowserActionsContainer::RefreshBrowserActionViews() {
456 for (size_t i = 0; i < browser_action_views_.size(); ++i) 424 for (size_t i = 0; i < browser_action_views_.size(); ++i)
457 browser_action_views_[i]->button()->UpdateState(); 425 browser_action_views_[i]->button()->UpdateState();
458 } 426 }
459 427
460 void BrowserActionsContainer::CloseOverflowMenu() {
461 if (overflow_menu_)
462 overflow_menu_->CancelMenu();
463 }
464
465 void BrowserActionsContainer::StopShowFolderDropMenuTimer() {
466 show_menu_task_factory_.RevokeAll();
467 }
468
469 void BrowserActionsContainer::StartShowFolderDropMenuTimer() {
470 int delay = View::GetMenuShowDelay();
471 MessageLoop::current()->PostDelayedTask(FROM_HERE,
472 show_menu_task_factory_.NewRunnableMethod(
473 &BrowserActionsContainer::ShowDropFolder),
474 delay);
475 }
476
477 void BrowserActionsContainer::ShowDropFolder() {
478 DCHECK(!overflow_menu_);
479 SetDropIndicator(-1);
480 overflow_menu_ = new BrowserActionOverflowMenuController(
481 this, chevron_, browser_action_views_, VisibleBrowserActions());
482 overflow_menu_->set_observer(this);
483 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true);
484 }
485
486 void BrowserActionsContainer::SetDropIndicator(int x_pos) {
487 if (drop_indicator_position_ != x_pos) {
488 drop_indicator_position_ = x_pos;
489 SchedulePaint();
490 }
491 }
492
493 void BrowserActionsContainer::CreateBrowserActionViews() { 428 void BrowserActionsContainer::CreateBrowserActionViews() {
494 DCHECK(browser_action_views_.empty()); 429 DCHECK(browser_action_views_.empty());
495 if (!model_) 430 if (!model_)
496 return; 431 return;
497 432
498 for (ExtensionList::iterator iter = model_->begin(); 433 for (ExtensionList::iterator iter = model_->begin(); iter != model_->end();
499 iter != model_->end(); ++iter) { 434 ++iter) {
500 if (!ShouldDisplayBrowserAction(*iter)) 435 if (!ShouldDisplayBrowserAction(*iter))
501 continue; 436 continue;
502 437
503 BrowserActionView* view = new BrowserActionView(*iter, this); 438 BrowserActionView* view = new BrowserActionView(*iter, this);
504 browser_action_views_.push_back(view); 439 browser_action_views_.push_back(view);
505 AddChildView(view); 440 AddChildView(view);
506 } 441 }
507 } 442 }
508 443
509 void BrowserActionsContainer::DeleteBrowserActionViews() { 444 void BrowserActionsContainer::DeleteBrowserActionViews() {
510 if (!browser_action_views_.empty()) { 445 if (!browser_action_views_.empty()) {
511 for (size_t i = 0; i < browser_action_views_.size(); ++i) 446 for (size_t i = 0; i < browser_action_views_.size(); ++i)
512 RemoveChildView(browser_action_views_[i]); 447 RemoveChildView(browser_action_views_[i]);
513 STLDeleteContainerPointers(browser_action_views_.begin(), 448 STLDeleteContainerPointers(browser_action_views_.begin(),
514 browser_action_views_.end()); 449 browser_action_views_.end());
515 browser_action_views_.clear(); 450 browser_action_views_.clear();
516 } 451 }
517 } 452 }
518 453
519 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { 454 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
520 SetVisible(browser_action_views_.size() > 0); 455 SetVisible(!browser_action_views_.empty());
521 owner_view_->Layout(); 456 owner_view_->Layout();
522 owner_view_->SchedulePaint(); 457 owner_view_->SchedulePaint();
523 } 458 }
524 459
525 void BrowserActionsContainer::HidePopup() { 460 size_t BrowserActionsContainer::VisibleBrowserActions() const {
526 if (popup_) 461 size_t visible_actions = 0;
527 popup_->Close(); 462 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
528 } 463 if (browser_action_views_[i]->IsVisible())
529 464 ++visible_actions;
530 void BrowserActionsContainer::TestExecuteBrowserAction(int index) { 465 }
531 BrowserActionButton* button = browser_action_views_[index]->button(); 466 return visible_actions;
532 OnBrowserActionExecuted(button, false); // |inspect_with_devtools|.
533 }
534
535 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
536 chevron_->SetVisible(icons < browser_action_views_.size());
537 container_size_.set_width(IconCountToWidth(icons));
538 Layout();
539 SchedulePaint();
540 } 467 }
541 468
542 void BrowserActionsContainer::OnBrowserActionExecuted( 469 void BrowserActionsContainer::OnBrowserActionExecuted(
543 BrowserActionButton* button, bool inspect_with_devtools) { 470 BrowserActionButton* button,
471 bool inspect_with_devtools) {
544 ExtensionAction* browser_action = button->browser_action(); 472 ExtensionAction* browser_action = button->browser_action();
545 473
546 // Popups just display. No notification to the extension. 474 // Popups just display. No notification to the extension.
547 // TODO(erikkay): should there be? 475 // TODO(erikkay): should there be?
548 if (button->IsPopup()) { 476 if (!button->IsPopup()) {
549 // If we're showing the same popup, just hide it and return. 477 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
550 bool same_showing = popup_ && button == popup_button_; 478 profile_, browser_action->extension_id(), browser_);
551
552 // Always hide the current popup, even if it's not the same.
553 // Only one popup should be visible at a time.
554 HidePopup();
555
556 if (same_showing)
557 return;
558
559 // We can get the execute event for browser actions that are not visible,
560 // since buttons can be activated from the overflow menu (chevron). In that
561 // case we show the popup as originating from the chevron.
562 View* reference_view = button->GetParent()->IsVisible() ? button : chevron_;
563 gfx::Point origin;
564 View::ConvertPointToScreen(reference_view, &origin);
565 gfx::Rect rect = reference_view->bounds();
566 rect.set_x(origin.x());
567 rect.set_y(origin.y());
568
569 gfx::NativeWindow frame_window =
570 browser_->window()->GetNativeHandle();
571 BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
572 BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
573
574 popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_,
575 browser_->profile(), frame_window, rect, arrow_location,
576 true, // Activate the popup window.
577 inspect_with_devtools,
578 ExtensionPopup::BUBBLE_CHROME,
579 this); // ExtensionPopupDelegate
580 popup_button_ = button;
581 popup_button_->SetButtonPushed();
582
583 return; 479 return;
584 } 480 }
585 481
586 // Otherwise, we send the action to the extension. 482 // If we're showing the same popup, just hide it and return.
587 ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted( 483 bool same_showing = popup_ && button == popup_button_;
588 profile_, browser_action->extension_id(), browser_); 484
485 // Always hide the current popup, even if it's not the same.
486 // Only one popup should be visible at a time.
487 HidePopup();
488
489 if (same_showing)
490 return;
491
492 // We can get the execute event for browser actions that are not visible,
493 // since buttons can be activated from the overflow menu (chevron). In that
494 // case we show the popup as originating from the chevron.
495 View* reference_view = button->GetParent()->IsVisible() ? button : chevron_;
496 gfx::Point origin;
497 View::ConvertPointToScreen(reference_view, &origin);
498 gfx::Rect rect = reference_view->bounds();
499 rect.set_origin(origin);
500
501 gfx::NativeWindow frame_window = browser_->window()->GetNativeHandle();
502 BubbleBorder::ArrowLocation arrow_location = base::i18n::IsRTL() ?
503 BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
504
505 popup_ = ExtensionPopup::Show(button->GetPopupUrl(), browser_,
506 browser_->profile(), frame_window, rect, arrow_location, true,
507 inspect_with_devtools, ExtensionPopup::BUBBLE_CHROME, this);
508 popup_button_ = button;
509 popup_button_->SetButtonPushed();
589 } 510 }
590 511
591 gfx::Size BrowserActionsContainer::GetPreferredSize() { 512 gfx::Size BrowserActionsContainer::GetPreferredSize() {
592 if (browser_action_views_.empty()) 513 if (browser_action_views_.empty())
593 return gfx::Size(0, 0); 514 return gfx::Size(0, 0);
594 515
595 // We calculate the size of the view by taking the current width and 516 // We calculate the size of the view by taking the current width and
596 // subtracting resize_amount_ (the latter represents how far the user is 517 // subtracting resize_amount_ (the latter represents how far the user is
597 // resizing the view or, if animating the snapping, how far to animate it). 518 // resizing the view or, if animating the snapping, how far to animate it).
598 // But we also clamp it to a minimum size and the maximum size, so that the 519 // But we also clamp it to a minimum size and the maximum size, so that the
599 // container can never shrink too far or take up more space than it needs. In 520 // container can never shrink too far or take up more space than it needs. In
600 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX). 521 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX).
601 int width = std::max(ContainerMinSize(), 522 int clamped_width = std::min(
602 container_size_.width() - resize_amount_); 523 std::max(ContainerMinSize(), container_width_ - resize_amount_),
603 int max_width = ClampToNearestIconCount(-1, false); // -1 gives max width. 524 ClampToNearestIconCount(-1, false));
604 width = std::min(width, max_width); 525 return gfx::Size(clamped_width, kButtonSize);
605
606 return gfx::Size(width, kButtonSize);
607 } 526 }
608 527
609 void BrowserActionsContainer::Layout() { 528 void BrowserActionsContainer::Layout() {
610 // The parent can be visible, but collapsed. In this case we don't 529 // The parent can be visible, but collapsed. In this case we don't
611 // want the browser action container to be visible. 530 // want the browser action container to be visible.
612 ToolbarView* parent = reinterpret_cast<ToolbarView*>(GetParent()); 531 ToolbarView* parent = reinterpret_cast<ToolbarView*>(GetParent());
613 532
614 if (browser_action_views_.size() == 0 || parent->collapsed()) { 533 if (browser_action_views_.empty() || parent->collapsed()) {
615 SetVisible(false); 534 SetVisible(false);
616 chevron_->SetVisible(false); 535 chevron_->SetVisible(false);
617 return; 536 return;
618 } else {
619 SetVisible(true);
620 } 537 }
621 538
539 SetVisible(true);
540
622 resize_area_->SetBounds(0, 0, kResizeAreaWidth, height()); 541 resize_area_->SetBounds(0, 0, kResizeAreaWidth, height());
623 int x = kResizeAreaWidth; 542 int x = kResizeAreaWidth;
624 543
625 x += base::i18n::IsRTL() ? kHorizontalPaddingRtl : kHorizontalPadding; 544 x += base::i18n::IsRTL() ? kHorizontalPaddingRtl : kHorizontalPadding;
626 545
627 // Calculate if all icons fit without showing the chevron. We need to know 546 // Calculate if all icons fit without showing the chevron. We need to know
628 // this beforehand, because showing the chevron will decrease the space that 547 // this beforehand, because showing the chevron will decrease the space that
629 // we have to draw the visible ones (ie. if one icon is visible and another 548 // we have to draw the visible ones (ie. if one icon is visible and another
630 // doesn't have enough room). 549 // doesn't have enough room).
631 int last_x_of_icons = x + 550 int last_x_of_icons = x +
632 (browser_action_views_.size() * kButtonSize) + 551 (browser_action_views_.size() * kButtonSize) +
633 ((browser_action_views_.size() - 1) * 552 ((browser_action_views_.size() - 1) *
634 kBrowserActionButtonPadding); 553 kBrowserActionButtonPadding);
635 554
636 gfx::Size sz = GetPreferredSize(); 555 gfx::Size sz = GetPreferredSize();
637 int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin; 556 int max_x = sz.width() - kDividerHorizontalMargin - kChevronRightMargin;
638 557
639 // If they don't all fit, show the chevron (unless suppressed). 558 // If they don't all fit, show the chevron (unless suppressed).
640 gfx::Size chevron_size;
641 if (last_x_of_icons >= max_x && !suppress_chevron_) { 559 if (last_x_of_icons >= max_x && !suppress_chevron_) {
642 chevron_->SetVisible(true); 560 chevron_->SetVisible(true);
643 chevron_size = chevron_->GetPreferredSize(); 561 gfx::Size chevron_size(chevron_->GetPreferredSize());
644 max_x -= chevron_size.width(); 562 max_x -= chevron_size.width();
645 chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin, 563 chevron_->SetBounds(width() - chevron_size.width() - kChevronRightMargin,
646 kChevronTopMargin, 564 kChevronTopMargin,
647 chevron_size.width(), chevron_size.height()); 565 chevron_size.width(), chevron_size.height());
648 } else { 566 } else {
649 chevron_->SetVisible(false); 567 chevron_->SetVisible(false);
650 } 568 }
651 569
652 // Now draw the icons for the browser actions in the available space. 570 // Now draw the icons for the browser actions in the available space.
653 for (size_t i = 0; i < browser_action_views_.size(); ++i) { 571 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
(...skipping 14 matching lines...) Expand all
668 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) { 586 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) {
669 // The one-pixel themed vertical divider to the right of the browser actions. 587 // The one-pixel themed vertical divider to the right of the browser actions.
670 int x = base::i18n::IsRTL() ? 588 int x = base::i18n::IsRTL() ?
671 kDividerHorizontalMargin : (width() - kDividerHorizontalMargin); 589 kDividerHorizontalMargin : (width() - kDividerHorizontalMargin);
672 DetachableToolbarView::PaintVerticalDivider( 590 DetachableToolbarView::PaintVerticalDivider(
673 canvas, x, height(), kDividerVerticalPadding, 591 canvas, x, height(), kDividerVerticalPadding,
674 DetachableToolbarView::kEdgeDividerColor, 592 DetachableToolbarView::kEdgeDividerColor,
675 DetachableToolbarView::kMiddleDividerColor, 593 DetachableToolbarView::kMiddleDividerColor,
676 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); 594 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
677 595
678 // The two-pixel width drop indicator. 596 // TODO(sky/glen): Instead of using a drop indicator, animate the icons while
597 // dragging (like we do for tab dragging).
679 if (drop_indicator_position_ > -1) { 598 if (drop_indicator_position_ > -1) {
680 x = drop_indicator_position_; 599 // The two-pixel width drop indicator.
681 int y = kDividerVerticalPadding; 600 static const int kDropIndicatorWidth = 2;
682 gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2, 601 gfx::Rect indicator_bounds(
683 y, 602 drop_indicator_position_ - (kDropIndicatorWidth / 2),
684 kDropIndicatorWidth, 603 kDividerVerticalPadding, kDropIndicatorWidth,
685 height() - (2 * kDividerVerticalPadding)); 604 height() - (2 * kDividerVerticalPadding));
686 605
687 // TODO(sky/glen): make me pretty! 606 // Color of the drop indicator.
607 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
688 canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(), 608 canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(),
689 indicator_bounds.y(), indicator_bounds.width(), 609 indicator_bounds.y(), indicator_bounds.width(),
690 indicator_bounds.height()); 610 indicator_bounds.height());
691 } 611 }
692 } 612 }
693 613
694 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, 614 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
695 views::View* parent, 615 views::View* parent,
696 views::View* child) { 616 views::View* child) {
697 // No extensions (e.g., incognito). 617 // No extensions (e.g., incognito).
698 if (!model_) 618 if (!model_)
699 return; 619 return;
700 620
701 if (is_add && child == this) { 621 if (is_add && child == this) {
702 // Initial toolbar button creation and placement in the widget hierarchy. 622 // Initial toolbar button creation and placement in the widget hierarchy.
703 // We do this here instead of in the constructor because AddBrowserAction 623 // We do this here instead of in the constructor because AddBrowserAction
704 // calls Layout on the Toolbar, which needs this object to be constructed 624 // calls Layout on the Toolbar, which needs this object to be constructed
705 // before its Layout function is called. 625 // before its Layout function is called.
706 CreateBrowserActionViews(); 626 CreateBrowserActionViews();
707 } 627 }
708 } 628 }
709 629
710 bool BrowserActionsContainer::GetDropFormats( 630 bool BrowserActionsContainer::GetDropFormats(
711 int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) { 631 int* formats,
632 std::set<OSExchangeData::CustomFormat>* custom_formats) {
712 custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat()); 633 custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat());
713 634
714 return true; 635 return true;
715 } 636 }
716 637
717 bool BrowserActionsContainer::AreDropTypesRequired() { 638 bool BrowserActionsContainer::AreDropTypesRequired() {
718 return true; 639 return true;
719 } 640 }
720 641
721 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { 642 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
722 BrowserActionDragData drop_data; 643 BrowserActionDragData drop_data;
723 if (!drop_data.Read(data)) 644 return drop_data.Read(data) ? drop_data.IsFromProfile(profile_) : false;
724 return false;
725 return drop_data.IsFromProfile(profile_);
726 } 645 }
727 646
728 void BrowserActionsContainer::OnDragEntered( 647 void BrowserActionsContainer::OnDragEntered(
729 const views::DropTargetEvent& event) { 648 const views::DropTargetEvent& event) {
730 } 649 }
731 650
732 int BrowserActionsContainer::OnDragUpdated( 651 int BrowserActionsContainer::OnDragUpdated(
733 const views::DropTargetEvent& event) { 652 const views::DropTargetEvent& event) {
734 // First check if we are above the chevron (overflow) menu. 653 // First check if we are above the chevron (overflow) menu.
735 if (GetViewForPoint(event.location()) == chevron_) { 654 if (GetViewForPoint(event.location()) == chevron_) {
736 if (show_menu_task_factory_.empty() && !overflow_menu_) 655 if (show_menu_task_factory_.empty() && !overflow_menu_)
737 StartShowFolderDropMenuTimer(); 656 StartShowFolderDropMenuTimer();
738 return DragDropTypes::DRAG_MOVE; 657 return DragDropTypes::DRAG_MOVE;
739 } else {
740 StopShowFolderDropMenuTimer();
741 } 658 }
659 StopShowFolderDropMenuTimer();
742 660
743 // Modifying the x value before clamping affects how far you have to drag to 661 // Modifying the x value before clamping affects how far you have to drag to
744 // get the drop indicator to shift to another position. Modifying after 662 // get the drop indicator to shift to another position. Modifying after
745 // clamping affects where the drop indicator is drawn. 663 // clamping affects where the drop indicator is drawn.
746 664
747 // We add half a button size so that when you drag a button to the right and 665 // We add half a button size so that when you drag a button to the right and
748 // you are half-way dragging across a button the drop indicator moves from the 666 // you are half-way dragging across a button the drop indicator moves from the
749 // left of that button to the right of that button. 667 // left of that button to the right of that button.
750 int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding); 668 int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding);
751 if (chevron_->IsVisible()) 669 if (chevron_->IsVisible())
(...skipping 21 matching lines...) Expand all
773 SchedulePaint(); 691 SchedulePaint();
774 } 692 }
775 693
776 int BrowserActionsContainer::OnPerformDrop( 694 int BrowserActionsContainer::OnPerformDrop(
777 const views::DropTargetEvent& event) { 695 const views::DropTargetEvent& event) {
778 BrowserActionDragData data; 696 BrowserActionDragData data;
779 if (!data.Read(event.GetData())) 697 if (!data.Read(event.GetData()))
780 return DragDropTypes::DRAG_NONE; 698 return DragDropTypes::DRAG_NONE;
781 699
782 // Make sure we have the same view as we started with. 700 // Make sure we have the same view as we started with.
783 DCHECK(browser_action_views_[data.index()]->button()->extension()->id() == 701 DCHECK_EQ(browser_action_views_[data.index()]->button()->extension()->id(),
784 data.id()); 702 data.id());
785 DCHECK(model_); 703 DCHECK(model_);
786 704
787 Extension* dragging =
788 browser_action_views_[data.index()]->button()->extension();
789
790 int target_x = drop_indicator_position_;
791
792 size_t i = 0; 705 size_t i = 0;
793 for (; i < browser_action_views_.size(); ++i) { 706 for (; i < browser_action_views_.size(); ++i) {
794 int view_x = 707 int view_x =
795 browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x(); 708 browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x();
796 if (!browser_action_views_[i]->IsVisible() || 709 if (!browser_action_views_[i]->IsVisible() ||
797 (base::i18n::IsRTL() ? view_x < target_x : view_x >= target_x)) { 710 (base::i18n::IsRTL() ? (view_x < drop_indicator_position_) :
711 (view_x >= drop_indicator_position_))) {
798 // We have reached the end of the visible icons or found one that has a 712 // We have reached the end of the visible icons or found one that has a
799 // higher x position than the drop point. 713 // higher x position than the drop point.
800 break; 714 break;
801 } 715 }
802 } 716 }
803 717
804 // |i| now points to the item to the right of the drop indicator*, which is 718 // |i| now points to the item to the right of the drop indicator*, which is
805 // correct when dragging an icon to the left. When dragging to the right, 719 // correct when dragging an icon to the left. When dragging to the right,
806 // however, we want the icon being dragged to get the index of the item to 720 // however, we want the icon being dragged to get the index of the item to
807 // the left of the drop indicator, so we subtract one. 721 // the left of the drop indicator, so we subtract one.
808 // * Well, it can also point to the end, but not when dragging to the left. :) 722 // * Well, it can also point to the end, but not when dragging to the left. :)
809 if (i > data.index()) 723 if (i > data.index())
810 --i; 724 --i;
811 725
812 if (profile_->IsOffTheRecord()) 726 if (profile_->IsOffTheRecord())
813 i = model_->IncognitoIndexToOriginal(i); 727 i = model_->IncognitoIndexToOriginal(i);
814 728
815 model_->MoveBrowserAction(dragging, i); 729 model_->MoveBrowserAction(
730 browser_action_views_[data.index()]->button()->extension(), i);
816 731
817 OnDragExited(); // Perform clean up after dragging. 732 OnDragExited(); // Perform clean up after dragging.
818 return DragDropTypes::DRAG_MOVE; 733 return DragDropTypes::DRAG_MOVE;
819 } 734 }
820 735
821 bool BrowserActionsContainer::GetAccessibleRole( 736 bool BrowserActionsContainer::GetAccessibleRole(
822 AccessibilityTypes::Role* role) { 737 AccessibilityTypes::Role* role) {
823 DCHECK(role); 738 DCHECK(role);
824 *role = AccessibilityTypes::ROLE_GROUPING; 739 *role = AccessibilityTypes::ROLE_GROUPING;
825 return true; 740 return true;
826 } 741 }
827 742
828 void BrowserActionsContainer::MoveBrowserAction(
829 const std::string& extension_id, size_t new_index) {
830 ExtensionsService* service = profile_->GetExtensionsService();
831 if (service) {
832 Extension* extension = service->GetExtensionById(extension_id, false);
833 model_->MoveBrowserAction(extension, new_index);
834 SchedulePaint();
835 }
836 }
837
838 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) { 743 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) {
839 if (source == chevron_) { 744 if (source == chevron_) {
840 overflow_menu_ = new BrowserActionOverflowMenuController( 745 overflow_menu_ = new BrowserActionOverflowMenuController(
841 this, chevron_, browser_action_views_, VisibleBrowserActions()); 746 this, chevron_, browser_action_views_, VisibleBrowserActions());
842 overflow_menu_->set_observer(this); 747 overflow_menu_->set_observer(this);
843 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), false); 748 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), false);
844 } 749 }
845 } 750 }
846 751
847 void BrowserActionsContainer::WriteDragData(View* sender, 752 void BrowserActionsContainer::WriteDragData(View* sender,
(...skipping 23 matching lines...) Expand all
871 const gfx::Point& p) { 776 const gfx::Point& p) {
872 return DragDropTypes::DRAG_MOVE; 777 return DragDropTypes::DRAG_MOVE;
873 } 778 }
874 779
875 bool BrowserActionsContainer::CanStartDrag(View* sender, 780 bool BrowserActionsContainer::CanStartDrag(View* sender,
876 const gfx::Point& press_pt, 781 const gfx::Point& press_pt,
877 const gfx::Point& p) { 782 const gfx::Point& p) {
878 return true; 783 return true;
879 } 784 }
880 785
881 int BrowserActionsContainer::ClampToNearestIconCount( 786 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
882 int pixelWidth, bool allow_shrink_to_minimum) const { 787 if (!done_resizing) {
883 // Calculate the width of one icon. 788 resize_amount_ = resize_amount;
884 int icon_width = (kButtonSize + kBrowserActionButtonPadding); 789 OnBrowserActionVisibilityChanged();
790 } else {
791 // For details on why we do the following see the class comments in the
792 // header.
885 793
886 // Calculate pixel count for the area not used by the icons. 794 // Clamp lower limit to 0 and upper limit to the amount that allows enough
887 int extras = WidthOfNonIconArea(); 795 // room for all icons to show.
796 int new_width = std::max(0, container_width_ - resize_amount);
797 int max_width = ClampToNearestIconCount(-1, false);
798 new_width = std::min(new_width, max_width);
888 799
889 size_t icon_count = 0u; 800 // Up until now we've only been modifying the resize_amount, but now it is
890 if (pixelWidth >= 0) { 801 // time to set the container size to the size we have resized to, but then
891 // Caller wants to know how many icons fit within a given space so we start 802 // animate to the nearest icon count size (or down to min size if no icon).
892 // by subtracting the padding, resize area and dividers. 803 container_width_ = new_width;
893 int icon_area = pixelWidth - extras; 804 animation_target_size_ = ClampToNearestIconCount(new_width, true);
894 icon_area = std::max(0, icon_area); 805 resize_animation_->Reset();
806 resize_animation_->SetTweenType(Tween::EASE_OUT);
807 resize_animation_->Show();
808 }
809 }
895 810
896 // Make sure we never throw an icon into the chevron menu just because 811 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
897 // there isn't enough enough space for the invisible padding around buttons. 812 DCHECK_EQ(resize_animation_.get(), animation);
898 icon_area += kBrowserActionButtonPadding - 1; 813 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() *
814 (container_width_ - animation_target_size_));
815 OnBrowserActionVisibilityChanged();
816 }
899 817
900 // Count the number of icons that fit within that area. 818 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
901 icon_count = icon_area / icon_width; 819 container_width_ = animation_target_size_;
820 animation_target_size_ = 0;
821 resize_amount_ = 0;
822 OnBrowserActionVisibilityChanged();
823 suppress_chevron_ = false;
902 824
903 if (icon_count == 0 && allow_shrink_to_minimum) { 825 // Don't save the icon count in incognito because there may be fewer icons
904 extras = ContainerMinSize(); // Allow very narrow width if no icons. 826 // in that mode. The result is that the container in a normal window is always
905 } else if (icon_count > browser_action_views_.size()) { 827 // at least as wide as in an incognito window.
906 // No use allowing more than what we have. 828 if (!profile_->IsOffTheRecord())
907 icon_count = browser_action_views_.size(); 829 model_->SetVisibleIconCount(VisibleBrowserActions());
908 } 830 }
909 } else { 831
910 // A negative |pixels| count indicates caller wants to know the max width 832 void BrowserActionsContainer::NotifyMenuDeleted(
911 // that fits all icons; 833 BrowserActionOverflowMenuController* controller) {
912 icon_count = browser_action_views_.size(); 834 DCHECK(controller == overflow_menu_);
835 overflow_menu_ = NULL;
836 }
837
838 void BrowserActionsContainer::InspectPopup(ExtensionAction* action) {
839 OnBrowserActionExecuted(GetBrowserActionView(action)->button(), true);
840 }
841
842 void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) {
843 // ExtensionPopup is ref-counted, so we don't need to delete it.
844 DCHECK_EQ(popup_, popup);
845 popup_ = NULL;
846 popup_button_->SetButtonNotPushed();
847 popup_button_ = NULL;
848 }
849
850 void BrowserActionsContainer::MoveBrowserAction(const std::string& extension_id,
851 size_t new_index) {
852 ExtensionsService* service = profile_->GetExtensionsService();
853 if (service) {
854 Extension* extension = service->GetExtensionById(extension_id, false);
855 model_->MoveBrowserAction(extension, new_index);
856 SchedulePaint();
913 } 857 }
858 }
914 859
915 return extras + (icon_count * icon_width); 860 void BrowserActionsContainer::HidePopup() {
861 if (popup_)
862 popup_->Close();
863 }
864
865 void BrowserActionsContainer::TestExecuteBrowserAction(int index) {
866 BrowserActionButton* button = browser_action_views_[index]->button();
867 OnBrowserActionExecuted(button, false); // |inspect_with_devtools|.
868 }
869
870 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
871 chevron_->SetVisible(icons < browser_action_views_.size());
872 container_width_ = IconCountToWidth(icons);
873 Layout();
874 SchedulePaint();
916 } 875 }
917 876
918 void BrowserActionsContainer::BrowserActionAdded(Extension* extension, 877 void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
919 int index) { 878 int index) {
920 #if defined(DEBUG) 879 #if defined(DEBUG)
921 for (size_t i = 0; i < browser_action_views_.size(); ++i) { 880 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
922 DCHECK(browser_action_views_[i]->button()->extension() != extension) << 881 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
923 "Asked to add a browser action view for an extension that already " 882 "Asked to add a browser action view for an extension that already "
924 "exists."; 883 "exists.";
925 } 884 }
926 #endif 885 #endif
927 CloseOverflowMenu(); 886 CloseOverflowMenu();
928 887
929 if (!ShouldDisplayBrowserAction(extension)) 888 if (!ShouldDisplayBrowserAction(extension))
930 return; 889 return;
931 890
891 size_t visible_actions = VisibleBrowserActions();
892
893 // Add the new browser action to the vector and the view hierarchy.
932 if (profile_->IsOffTheRecord()) 894 if (profile_->IsOffTheRecord())
933 index = model_->OriginalIndexToIncognito(index); 895 index = model_->OriginalIndexToIncognito(index);
934 896
935 // Before we change anything, determine the number of visible browser actions.
936 size_t visible_actions = VisibleBrowserActions();
937
938 // Add the new browser action to the vector and the view hierarchy.
939 BrowserActionView* view = new BrowserActionView(extension, this); 897 BrowserActionView* view = new BrowserActionView(extension, this);
940 browser_action_views_.insert(browser_action_views_.begin() + index, view); 898 browser_action_views_.insert(browser_action_views_.begin() + index, view);
941 AddChildView(index, view); 899 AddChildView(index, view);
942 900
943 // If we are still initializing the container, don't bother animating. 901 // If we are still initializing the container, don't bother animating.
944 if (!model_->extensions_initialized()) 902 if (!model_->extensions_initialized())
945 return; 903 return;
946 904
947 // For details on why we do the following see the class comments in the 905 // For details on why we do the following see the class comments in the
948 // header. 906 // header.
(...skipping 14 matching lines...) Expand all
963 Animate(Tween::LINEAR, target_size); 921 Animate(Tween::LINEAR, target_size);
964 } 922 }
965 } 923 }
966 924
967 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) { 925 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
968 CloseOverflowMenu(); 926 CloseOverflowMenu();
969 927
970 if (popup_ && popup_->host()->extension() == extension) 928 if (popup_ && popup_->host()->extension() == extension)
971 HidePopup(); 929 HidePopup();
972 930
973 // Before we change anything, determine the number of visible browser
974 // actions.
975 size_t visible_actions = VisibleBrowserActions(); 931 size_t visible_actions = VisibleBrowserActions();
976 932 for (BrowserActionViews::iterator iter = browser_action_views_.begin();
977 for (BrowserActionViews::iterator iter = 933 iter != browser_action_views_.end(); ++iter) {
978 browser_action_views_.begin(); iter != browser_action_views_.end();
979 ++iter) {
980 if ((*iter)->button()->extension() == extension) { 934 if ((*iter)->button()->extension() == extension) {
981 RemoveChildView(*iter); 935 RemoveChildView(*iter);
982 delete *iter; 936 delete *iter;
983 browser_action_views_.erase(iter); 937 browser_action_views_.erase(iter);
984 938
985 // If the extension is being upgraded we don't want the bar to shrink 939 // If the extension is being upgraded we don't want the bar to shrink
986 // because the icon is just going to get re-added to the same location. 940 // because the icon is just going to get re-added to the same location.
987 if (extension->being_upgraded()) 941 if (extension->being_upgraded())
988 return; 942 return;
989 943
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 } 975 }
1022 976
1023 void BrowserActionsContainer::ModelLoaded() { 977 void BrowserActionsContainer::ModelLoaded() {
1024 SetContainerWidth(); 978 SetContainerWidth();
1025 } 979 }
1026 980
1027 void BrowserActionsContainer::SetContainerWidth() { 981 void BrowserActionsContainer::SetContainerWidth() {
1028 int visible_actions = model_->GetVisibleIconCount(); 982 int visible_actions = model_->GetVisibleIconCount();
1029 if (visible_actions < 0) // All icons should be visible. 983 if (visible_actions < 0) // All icons should be visible.
1030 visible_actions = model_->size(); 984 visible_actions = model_->size();
1031 else 985 chevron_->SetVisible(static_cast<size_t>(visible_actions) < model_->size());
1032 chevron_->SetVisible(true); 986 container_width_ = IconCountToWidth(visible_actions);
1033 container_size_ = gfx::Size(IconCountToWidth(visible_actions), kButtonSize); 987 }
988
989 void BrowserActionsContainer::CloseOverflowMenu() {
990 if (overflow_menu_)
991 overflow_menu_->CancelMenu();
992 }
993
994 void BrowserActionsContainer::StopShowFolderDropMenuTimer() {
995 show_menu_task_factory_.RevokeAll();
996 }
997
998 void BrowserActionsContainer::StartShowFolderDropMenuTimer() {
999 int delay = View::GetMenuShowDelay();
1000 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1001 show_menu_task_factory_.NewRunnableMethod(
1002 &BrowserActionsContainer::ShowDropFolder),
1003 delay);
1004 }
1005
1006 void BrowserActionsContainer::ShowDropFolder() {
1007 DCHECK(!overflow_menu_);
1008 SetDropIndicator(-1);
1009 overflow_menu_ = new BrowserActionOverflowMenuController(
1010 this, chevron_, browser_action_views_, VisibleBrowserActions());
1011 overflow_menu_->set_observer(this);
1012 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow(), true);
1013 }
1014
1015 void BrowserActionsContainer::SetDropIndicator(int x_pos) {
1016 if (drop_indicator_position_ != x_pos) {
1017 drop_indicator_position_ = x_pos;
1018 SchedulePaint();
1019 }
1020 }
1021
1022 int BrowserActionsContainer::ClampToNearestIconCount(
1023 int pixelWidth,
1024 bool allow_shrink_to_minimum) const {
1025 // Calculate the width of one icon.
1026 int icon_width = (kButtonSize + kBrowserActionButtonPadding);
1027
1028 // Calculate pixel count for the area not used by the icons.
1029 int extras = WidthOfNonIconArea();
1030
1031 size_t icon_count = 0u;
1032 if (pixelWidth >= 0) {
1033 // Caller wants to know how many icons fit within a given space so we start
1034 // by subtracting the padding, resize area and dividers.
1035 int icon_area = pixelWidth - extras;
1036 icon_area = std::max(0, icon_area);
1037
1038 // Make sure we never throw an icon into the chevron menu just because
1039 // there isn't enough enough space for the invisible padding around buttons.
1040 icon_area += kBrowserActionButtonPadding - 1;
1041
1042 // Count the number of icons that fit within that area.
1043 icon_count = icon_area / icon_width;
1044
1045 if (icon_count == 0 && allow_shrink_to_minimum) {
1046 extras = ContainerMinSize(); // Allow very narrow width if no icons.
1047 } else if (icon_count > browser_action_views_.size()) {
1048 // No use allowing more than what we have.
1049 icon_count = browser_action_views_.size();
1050 }
1051 } else {
1052 // A negative |pixels| count indicates caller wants to know the max width
1053 // that fits all icons;
1054 icon_count = browser_action_views_.size();
1055 }
1056
1057 return extras + (icon_count * icon_width);
1034 } 1058 }
1035 1059
1036 int BrowserActionsContainer::WidthOfNonIconArea() const { 1060 int BrowserActionsContainer::WidthOfNonIconArea() const {
1037 int chevron_size = (chevron_->IsVisible()) ? 1061 int chevron_size = (chevron_->IsVisible()) ?
1038 chevron_->GetPreferredSize().width() : 0; 1062 chevron_->GetPreferredSize().width() : 0;
1039 int padding = base::i18n::IsRTL() ? 1063 int padding = base::i18n::IsRTL() ?
1040 kHorizontalPaddingRtl : kHorizontalPadding; 1064 kHorizontalPaddingRtl : kHorizontalPadding;
1041 return kResizeAreaWidth + padding + chevron_size + kChevronRightMargin + 1065 return kResizeAreaWidth + padding + chevron_size + kChevronRightMargin +
1042 kDividerHorizontalMargin; 1066 kDividerHorizontalMargin;
1043 } 1067 }
(...skipping 19 matching lines...) Expand all
1063 resize_animation_->Reset(); 1087 resize_animation_->Reset();
1064 resize_animation_->SetTweenType(tween_type); 1088 resize_animation_->SetTweenType(tween_type);
1065 animation_target_size_ = target_size; 1089 animation_target_size_ = target_size;
1066 resize_animation_->Show(); 1090 resize_animation_->Show();
1067 } else { 1091 } else {
1068 animation_target_size_ = target_size; 1092 animation_target_size_ = target_size;
1069 AnimationEnded(resize_animation_.get()); 1093 AnimationEnded(resize_animation_.get());
1070 } 1094 }
1071 } 1095 }
1072 1096
1073 size_t BrowserActionsContainer::VisibleBrowserActions() const {
1074 size_t visible_actions = 0;
1075 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
1076 if (browser_action_views_[i]->IsVisible())
1077 ++visible_actions;
1078 }
1079
1080 return visible_actions;
1081 }
1082
1083 void BrowserActionsContainer::OnResize(int resize_amount, bool done_resizing) {
1084 if (!done_resizing) {
1085 resize_amount_ = resize_amount;
1086 OnBrowserActionVisibilityChanged();
1087 } else {
1088 // For details on why we do the following see the class comments in the
1089 // header.
1090
1091 // Clamp lower limit to 0 and upper limit to the amount that allows enough
1092 // room for all icons to show.
1093 int new_width = std::max(0, container_size_.width() - resize_amount);
1094 int max_width = ClampToNearestIconCount(-1, false);
1095 new_width = std::min(new_width, max_width);
1096
1097 // Up until now we've only been modifying the resize_amount, but now it is
1098 // time to set the container size to the size we have resized to, but then
1099 // animate to the nearest icon count size (or down to min size if no icon).
1100 container_size_.set_width(new_width);
1101 animation_target_size_ = ClampToNearestIconCount(new_width, true);
1102 resize_animation_->Reset();
1103 resize_animation_->SetTweenType(Tween::EASE_OUT);
1104 resize_animation_->Show();
1105 }
1106 }
1107
1108 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
1109 DCHECK(animation == resize_animation_.get());
1110
1111 double e = resize_animation_->GetCurrentValue();
1112 int difference = container_size_.width() - animation_target_size_;
1113
1114 resize_amount_ = static_cast<int>(e * difference);
1115
1116 OnBrowserActionVisibilityChanged();
1117 }
1118
1119 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
1120 container_size_.set_width(animation_target_size_);
1121 animation_target_size_ = 0;
1122 resize_amount_ = 0;
1123 OnBrowserActionVisibilityChanged();
1124 suppress_chevron_ = false;
1125
1126 // Don't save the icon count in incognito because there may be fewer icons
1127 // in that mode. The result is that the container in a normal window is always
1128 // at least as wide as in an incognito window.
1129 if (!profile_->IsOffTheRecord())
1130 model_->SetVisibleIconCount(VisibleBrowserActions());
1131 }
1132
1133 void BrowserActionsContainer::NotifyMenuDeleted(
1134 BrowserActionOverflowMenuController* controller) {
1135 DCHECK(controller == overflow_menu_);
1136 overflow_menu_ = NULL;
1137 }
1138
1139 void BrowserActionsContainer::InspectPopup(
1140 ExtensionAction* action) {
1141 OnBrowserActionExecuted(GetBrowserActionView(action)->button(),
1142 true); // |inspect_with_devtools|.
1143 }
1144
1145 void BrowserActionsContainer::ExtensionPopupIsClosing(ExtensionPopup* popup) {
1146 // ExtensionPopup is ref-counted, so we don't need to delete it.
1147 DCHECK_EQ(popup_, popup);
1148 popup_ = NULL;
1149 popup_button_->SetButtonNotPushed();
1150 popup_button_ = NULL;
1151 }
1152
1153 bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) { 1097 bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) {
1154 // Only display incognito-enabled extensions while in incognito mode. 1098 // Only display incognito-enabled extensions while in incognito mode.
1155 return (!profile_->IsOffTheRecord() || 1099 return (!profile_->IsOffTheRecord() ||
1156 profile_->GetExtensionsService()->IsIncognitoEnabled(extension)); 1100 profile_->GetExtensionsService()->IsIncognitoEnabled(extension));
1157 } 1101 }
OLDNEW
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | chrome/browser/views/browser_actions_container_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698