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

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

Issue 549224: Support reordering of Browser Actions within the container. Currently does no... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 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/gfx/canvas.h" 7 #include "app/gfx/canvas.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"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "chrome/browser/browser.h" 12 #include "chrome/browser/browser.h"
13 #include "chrome/browser/browser_theme_provider.h" 13 #include "chrome/browser/browser_theme_provider.h"
14 #include "chrome/browser/browser_window.h" 14 #include "chrome/browser/browser_window.h"
15 #include "chrome/browser/extensions/extension_browser_event_router.h" 15 #include "chrome/browser/extensions/extension_browser_event_router.h"
16 #include "chrome/browser/extensions/extensions_service.h" 16 #include "chrome/browser/extensions/extensions_service.h"
17 #include "chrome/browser/extensions/extension_tabs_module.h" 17 #include "chrome/browser/extensions/extension_tabs_module.h"
18 #include "chrome/browser/renderer_host/render_widget_host_view.h" 18 #include "chrome/browser/renderer_host/render_widget_host_view.h"
19 #include "chrome/browser/profile.h" 19 #include "chrome/browser/profile.h"
20 #include "chrome/browser/view_ids.h" 20 #include "chrome/browser/view_ids.h"
21 #include "chrome/browser/views/detachable_toolbar_view.h" 21 #include "chrome/browser/views/detachable_toolbar_view.h"
22 #include "chrome/browser/views/extensions/browser_action_drag_data.h"
22 #include "chrome/browser/views/extensions/browser_action_overflow_menu_controlle r.h" 23 #include "chrome/browser/views/extensions/browser_action_overflow_menu_controlle r.h"
23 #include "chrome/browser/views/extensions/extension_popup.h" 24 #include "chrome/browser/views/extensions/extension_popup.h"
24 #include "chrome/browser/views/toolbar_view.h" 25 #include "chrome/browser/views/toolbar_view.h"
25 #include "chrome/common/notification_source.h" 26 #include "chrome/common/notification_source.h"
26 #include "chrome/common/notification_type.h" 27 #include "chrome/common/notification_type.h"
27 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
28 #include "grit/app_resources.h" 29 #include "grit/app_resources.h"
29 #include "third_party/skia/include/core/SkBitmap.h" 30 #include "third_party/skia/include/core/SkBitmap.h"
30 #include "third_party/skia/include/core/SkTypeface.h" 31 #include "third_party/skia/include/core/SkTypeface.h"
31 #include "third_party/skia/include/effects/SkGradientShader.h" 32 #include "third_party/skia/include/effects/SkGradientShader.h"
32 #include "views/controls/button/menu_button.h" 33 #include "views/controls/button/menu_button.h"
33 #include "views/controls/button/text_button.h" 34 #include "views/controls/button/text_button.h"
34 #include "views/window/window.h" 35 #include "views/window/window.h"
35 36
36 #include "grit/theme_resources.h" 37 #include "grit/theme_resources.h"
37 38
38 // The size (both dimensions) of the buttons for page actions. 39 // The size (both dimensions) of the buttons for page actions.
39 static const int kButtonSize = 29; 40 static const int kButtonSize = 29;
40 41
41 // The padding between the browser actions and the OmniBox/page menu. 42 // The padding between the browser actions and the OmniBox/page menu.
42 static const int kHorizontalPadding = 4; 43 static const int kHorizontalPadding = 4;
44 static const int kHorizontalPaddingRtl = 8;
43 45
44 // The padding between browser action buttons. Visually, the actual number of 46 // The padding between browser action buttons. Visually, the actual number of
45 // empty (non-drawing) pixels is this value + 2 when adjacent browser icons 47 // empty (non-drawing) pixels is this value + 2 when adjacent browser icons
46 // use their maximum allowed size. 48 // use their maximum allowed size.
47 static const int kBrowserActionButtonPadding = 3; 49 static const int kBrowserActionButtonPadding = 3;
48 50
49 // This is the same value from toolbar.cc. We position the browser actions 51 // This is the same value from toolbar.cc. We position the browser actions
50 // container flush with the edges of the toolbar as a special case so that we 52 // container flush with the edges of the toolbar as a special case so that we
51 // can draw the badge outside the visual bounds of the container. 53 // can draw the badge outside the visual bounds of the container.
52 static const int kControlVertOffset = 6; 54 static const int kControlVertOffset = 6;
53 55
54 // The margin between the divider and the chrome menu buttons. 56 // The margin between the divider and the chrome menu buttons.
55 static const int kDividerHorizontalMargin = 2; 57 static const int kDividerHorizontalMargin = 2;
56 58
57 // The padding above and below the divider. 59 // The padding above and below the divider.
58 static const int kDividerVerticalPadding = 9; 60 static const int kDividerVerticalPadding = 9;
59 61
60 // The margin above the chevron. 62 // The margin above the chevron.
61 static const int kChevronTopMargin = 9; 63 static const int kChevronTopMargin = 9;
62 64
63 // The margin to the right of the chevron. 65 // The margin to the right of the chevron.
64 static const int kChevronRightMargin = 4; 66 static const int kChevronRightMargin = 4;
65 67
66 // Extra hit-area for the resize gripper. 68 // Extra hit-area for the resize gripper.
67 static const int kExtraResizeArea = 4; 69 static const int kExtraResizeArea = 4;
68 70
71 // Width of the drop indicator.
72 static const int kDropIndicatorWidth = 2;
73
74 // Color of the drop indicator.
75 static const SkColor kDropIndicatorColor = SK_ColorBLACK;
76
77 // The x offset for the drop indicator (how much we shift it by).
78 static const int kDropIndicatorOffsetLtr = 3;
79 static const int kDropIndicatorOffsetRtl = 9;
80
69 //////////////////////////////////////////////////////////////////////////////// 81 ////////////////////////////////////////////////////////////////////////////////
70 // BrowserActionButton 82 // BrowserActionButton
71 83
72 BrowserActionButton::BrowserActionButton(Extension* extension, 84 BrowserActionButton::BrowserActionButton(Extension* extension,
73 BrowserActionsContainer* panel) 85 BrowserActionsContainer* panel)
74 : MenuButton(this, L"", NULL, false), 86 : MenuButton(this, L"", NULL, false),
75 browser_action_(extension->browser_action()), 87 browser_action_(extension->browser_action()),
76 extension_(extension), 88 extension_(extension),
77 tracker_(NULL), 89 tracker_(NULL),
78 showing_context_menu_(false), 90 showing_context_menu_(false),
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 263 }
252 264
253 265
254 //////////////////////////////////////////////////////////////////////////////// 266 ////////////////////////////////////////////////////////////////////////////////
255 // BrowserActionView 267 // BrowserActionView
256 268
257 BrowserActionView::BrowserActionView(Extension* extension, 269 BrowserActionView::BrowserActionView(Extension* extension,
258 BrowserActionsContainer* panel) 270 BrowserActionsContainer* panel)
259 : panel_(panel) { 271 : panel_(panel) {
260 button_ = new BrowserActionButton(extension, panel); 272 button_ = new BrowserActionButton(extension, panel);
273 button_->SetDragController(panel_);
261 AddChildView(button_); 274 AddChildView(button_);
262 button_->UpdateState(); 275 button_->UpdateState();
263 } 276 }
264 277
265 void BrowserActionView::Layout() { 278 void BrowserActionView::Layout() {
266 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize); 279 button_->SetBounds(0, kControlVertOffset, width(), kButtonSize);
267 } 280 }
268 281
269 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) { 282 void BrowserActionView::PaintChildren(gfx::Canvas* canvas) {
270 View::PaintChildren(canvas); 283 View::PaintChildren(canvas);
(...skipping 13 matching lines...) Expand all
284 : profile_(profile), 297 : profile_(profile),
285 toolbar_(toolbar), 298 toolbar_(toolbar),
286 popup_(NULL), 299 popup_(NULL),
287 popup_button_(NULL), 300 popup_button_(NULL),
288 model_(NULL), 301 model_(NULL),
289 resize_gripper_(NULL), 302 resize_gripper_(NULL),
290 chevron_(NULL), 303 chevron_(NULL),
291 suppress_chevron_(false), 304 suppress_chevron_(false),
292 resize_amount_(0), 305 resize_amount_(0),
293 animation_target_size_(0), 306 animation_target_size_(0),
307 drop_indicator_position_(-1),
294 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { 308 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
295 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR); 309 SetID(VIEW_ID_BROWSER_ACTION_TOOLBAR);
296 310
297 ExtensionsService* extension_service = profile->GetExtensionsService(); 311 ExtensionsService* extension_service = profile->GetExtensionsService();
298 if (!extension_service) // The |extension_service| can be NULL in Incognito. 312 if (!extension_service) // The |extension_service| can be NULL in Incognito.
299 return; 313 return;
300 314
301 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 315 registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
302 Source<Profile>(profile_)); 316 Source<Profile>(profile_));
303 317
(...skipping 10 matching lines...) Expand all
314 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS); 328 SkBitmap* chevron_image = rb.GetBitmapNamed(IDR_BOOKMARK_BAR_CHEVRONS);
315 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false); 329 chevron_ = new views::MenuButton(NULL, std::wstring(), this, false);
316 chevron_->SetVisible(false); 330 chevron_->SetVisible(false);
317 chevron_->SetIcon(*chevron_image); 331 chevron_->SetIcon(*chevron_image);
318 // Chevron contains >> that should point left in LTR locales. 332 // Chevron contains >> that should point left in LTR locales.
319 chevron_->EnableCanvasFlippingForRTLUI(true); 333 chevron_->EnableCanvasFlippingForRTLUI(true);
320 AddChildView(chevron_); 334 AddChildView(chevron_);
321 335
322 int predefined_width = 336 int predefined_width =
323 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth); 337 profile_->GetPrefs()->GetInteger(prefs::kBrowserActionContainerWidth);
338 if (predefined_width == 0) {
339 // The width will never be 0 (due to container min size restriction)
340 // except when no width has been saved. So, in that case ask the model
341 // how many icons we'll show and set initial size to that.
342 predefined_width = IconCountToWidth(model_->size());
343 }
324 container_size_ = gfx::Size(predefined_width, kButtonSize); 344 container_size_ = gfx::Size(predefined_width, kButtonSize);
325 } 345 }
326 346
327 BrowserActionsContainer::~BrowserActionsContainer() { 347 BrowserActionsContainer::~BrowserActionsContainer() {
328 if (model_) 348 if (model_)
329 model_->RemoveObserver(this); 349 model_->RemoveObserver(this);
330 CloseOverflowMenu(); 350 CloseOverflowMenu();
331 HidePopup(); 351 HidePopup();
332 DeleteBrowserActionViews(); 352 DeleteBrowserActionViews();
333 } 353 }
(...skipping 27 matching lines...) Expand all
361 for (size_t i = 0; i < browser_action_views_.size(); ++i) 381 for (size_t i = 0; i < browser_action_views_.size(); ++i)
362 browser_action_views_[i]->button()->UpdateState(); 382 browser_action_views_[i]->button()->UpdateState();
363 } 383 }
364 384
365 void BrowserActionsContainer::CloseOverflowMenu() { 385 void BrowserActionsContainer::CloseOverflowMenu() {
366 // Close the overflow menu if open (and the context menu off of that). 386 // Close the overflow menu if open (and the context menu off of that).
367 if (overflow_menu_.get()) 387 if (overflow_menu_.get())
368 overflow_menu_->CancelMenu(); 388 overflow_menu_->CancelMenu();
369 } 389 }
370 390
391 void BrowserActionsContainer::CreateBrowserActionViews() {
392 DCHECK(browser_action_views_.empty());
393 for (ExtensionList::iterator iter = model_->begin();
394 iter != model_->end(); ++iter) {
395 BrowserActionView* view = new BrowserActionView(*iter, this);
396 browser_action_views_.push_back(view);
397 AddChildView(view);
398 }
399 }
400
371 void BrowserActionsContainer::DeleteBrowserActionViews() { 401 void BrowserActionsContainer::DeleteBrowserActionViews() {
372 if (!browser_action_views_.empty()) { 402 if (!browser_action_views_.empty()) {
373 for (size_t i = 0; i < browser_action_views_.size(); ++i) 403 for (size_t i = 0; i < browser_action_views_.size(); ++i)
374 RemoveChildView(browser_action_views_[i]); 404 RemoveChildView(browser_action_views_[i]);
375 STLDeleteContainerPointers(browser_action_views_.begin(), 405 STLDeleteContainerPointers(browser_action_views_.begin(),
376 browser_action_views_.end()); 406 browser_action_views_.end());
377 browser_action_views_.clear(); 407 browser_action_views_.clear();
378 } 408 }
379 } 409 }
380 410
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 return gfx::Size(0, 0); 496 return gfx::Size(0, 0);
467 497
468 // We calculate the size of the view by taking the current width and 498 // We calculate the size of the view by taking the current width and
469 // subtracting resize_amount_ (the latter represents how far the user is 499 // subtracting resize_amount_ (the latter represents how far the user is
470 // resizing the view or, if animating the snapping, how far to animate it). 500 // resizing the view or, if animating the snapping, how far to animate it).
471 // But we also clamp it to a minimum size and the maximum size, so that the 501 // But we also clamp it to a minimum size and the maximum size, so that the
472 // container can never shrink too far or take up more space than it needs. In 502 // container can never shrink too far or take up more space than it needs. In
473 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX). 503 // other words: ContainerMinSize() < width() - resize < ClampTo(MAX).
474 int width = std::max(ContainerMinSize(), 504 int width = std::max(ContainerMinSize(),
475 container_size_.width() - resize_amount_); 505 container_size_.width() - resize_amount_);
476 int max_width = ClampToNearestIconCount(-1); // -1 gives max width. 506 int max_width = ClampToNearestIconCount(-1, false); // -1 gives max width.
477 width = std::min(width, max_width); 507 width = std::min(width, max_width);
478 508
479 return gfx::Size(width, kButtonSize); 509 return gfx::Size(width, kButtonSize);
480 } 510 }
481 511
482 void BrowserActionsContainer::Layout() { 512 void BrowserActionsContainer::Layout() {
483 if (!resize_gripper_ || !chevron_) 513 if (!resize_gripper_ || !chevron_)
484 return; // These classes are not created in Incognito mode. 514 return; // These classes are not created in Incognito mode.
485 if (browser_action_views_.size() == 0) { 515 if (browser_action_views_.size() == 0) {
486 resize_gripper_->SetVisible(false); 516 resize_gripper_->SetVisible(false);
487 chevron_->SetVisible(false); 517 chevron_->SetVisible(false);
488 return; 518 return;
489 } 519 }
490 520
491 int x = 0; 521 int x = 0;
492 if (resize_gripper_->IsVisible()) { 522 if (resize_gripper_->IsVisible()) {
493 // We'll draw the resize gripper a little wider, to add some invisible hit 523 // We'll draw the resize gripper a little wider, to add some invisible hit
494 // target area - but we don't account for it anywhere. 524 // target area - but we don't account for it anywhere.
495 gfx::Size sz = resize_gripper_->GetPreferredSize(); 525 gfx::Size sz = resize_gripper_->GetPreferredSize();
496 resize_gripper_->SetBounds(x, (height() - sz.height()) / 2 + 1, 526 resize_gripper_->SetBounds(x, (height() - sz.height()) / 2 + 1,
497 sz.width() + kExtraResizeArea, sz.height()); 527 sz.width() + kExtraResizeArea, sz.height());
498 x += sz.width(); 528 x += sz.width();
499 } 529 }
500 530
501 x += kHorizontalPadding; 531 x += UILayoutIsRightToLeft() ? kHorizontalPaddingRtl : kHorizontalPadding;
502 532
503 // Calculate if all icons fit without showing the chevron. We need to know 533 // Calculate if all icons fit without showing the chevron. We need to know
504 // this beforehand, because showing the chevron will decrease the space that 534 // this beforehand, because showing the chevron will decrease the space that
505 // we have to draw the visible ones (ie. if one icon is visible and another 535 // we have to draw the visible ones (ie. if one icon is visible and another
506 // doesn't have enough room). 536 // doesn't have enough room).
507 int last_x_of_icons = x + 537 int last_x_of_icons = x +
508 (browser_action_views_.size() * kButtonSize) + 538 (browser_action_views_.size() * kButtonSize) +
509 ((browser_action_views_.size() - 1) * 539 ((browser_action_views_.size() - 1) *
510 kBrowserActionButtonPadding); 540 kBrowserActionButtonPadding);
511 541
(...skipping 30 matching lines...) Expand all
542 572
543 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) { 573 void BrowserActionsContainer::Paint(gfx::Canvas* canvas) {
544 // The one-pixel themed vertical divider to the right of the browser actions. 574 // The one-pixel themed vertical divider to the right of the browser actions.
545 int x = UILayoutIsRightToLeft() ? kDividerHorizontalMargin : 575 int x = UILayoutIsRightToLeft() ? kDividerHorizontalMargin :
546 width() - kDividerHorizontalMargin; 576 width() - kDividerHorizontalMargin;
547 DetachableToolbarView::PaintVerticalDivider( 577 DetachableToolbarView::PaintVerticalDivider(
548 canvas, x, height(), kDividerVerticalPadding, 578 canvas, x, height(), kDividerVerticalPadding,
549 DetachableToolbarView::kEdgeDividerColor, 579 DetachableToolbarView::kEdgeDividerColor,
550 DetachableToolbarView::kMiddleDividerColor, 580 DetachableToolbarView::kMiddleDividerColor,
551 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); 581 GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR));
582
583 // The two-pixel width drop indicator.
584 if (drop_indicator_position_ > -1) {
585 x = drop_indicator_position_;
586 int y = kDividerVerticalPadding;
587 gfx::Rect indicator_bounds(x - kDropIndicatorWidth / 2,
588 y,
589 kDropIndicatorWidth,
590 height() - (2 * kDividerVerticalPadding));
591
592 // TODO(sky/glen): make me pretty!
593 canvas->FillRectInt(kDropIndicatorColor, indicator_bounds.x(),
594 indicator_bounds.y(), indicator_bounds.width(),
595 indicator_bounds.height());
596 }
552 } 597 }
553 598
554 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add, 599 void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
555 views::View* parent, 600 views::View* parent,
556 views::View* child) { 601 views::View* child) {
557 // No extensions (e.g., incognito). 602 // No extensions (e.g., incognito).
558 if (!model_) 603 if (!model_)
559 return; 604 return;
560 605
561 if (is_add && child == this) { 606 if (is_add && child == this) {
562 // Initial toolbar button creation and placement in the widget hierarchy. 607 // Initial toolbar button creation and placement in the widget hierarchy.
563 // We do this here instead of in the constructor because AddBrowserAction 608 // We do this here instead of in the constructor because AddBrowserAction
564 // calls Layout on the Toolbar, which needs this object to be constructed 609 // calls Layout on the Toolbar, which needs this object to be constructed
565 // before its Layout function is called. 610 // before its Layout function is called.
566 for (ExtensionList::iterator iter = model_->begin(); 611 CreateBrowserActionViews();
567 iter != model_->end(); ++iter) {
568 BrowserActionView* view = new BrowserActionView(*iter, this);
569 browser_action_views_.push_back(view);
570 AddChildView(view);
571 }
572 } 612 }
573 } 613 }
574 614
615 bool BrowserActionsContainer::GetDropFormats(
616 int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) {
617 custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat());
618 return true;
619 }
620
621 bool BrowserActionsContainer::AreDropTypesRequired() {
622 return true;
623 }
624
625 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
626 BrowserActionDragData drop_data;
627 if (!drop_data.Read(data))
628 return false;
629 return drop_data.IsFromProfile(profile_);
630 }
631
632 void BrowserActionsContainer::OnDragEntered(
633 const views::DropTargetEvent& event) {
634 }
635
636 int BrowserActionsContainer::OnDragUpdated(
637 const views::DropTargetEvent& event) {
638 // Modifying the x value before clamping affects how far you have to drag to
639 // get the drop indicator to shift to another position. Modifying after
640 // clamping affects where the drop indicator is drawn.
641
642 // We add half a button size so that when you drag a button to the right and
643 // you are half-way dragging across a button the drop indicator moves from the
644 // left of that button to the right of that button.
645 int x = event.x() + (kButtonSize / 2) + (2 * kBrowserActionButtonPadding);
646 if (chevron_->IsVisible())
647 x += chevron_->bounds().width();
648 x = ClampToNearestIconCount(x, false);
649
650 if (!UILayoutIsRightToLeft() && chevron_->IsVisible()) {
651 // The clamping function includes the chevron width. In LTR locales, the
652 // chevron is on the right and we never want to account for its width. In
653 // RTL it is on the left and we always want to count the width.
654 x -= chevron_->width();
655 }
656
657 // Clamping gives us a value where the next button will be drawn, but we want
658 // to subtract the padding (and then some) to make it appear in-between the
659 // buttons.
660 drop_indicator_position_ = x - kBrowserActionButtonPadding -
661 (UILayoutIsRightToLeft() ? kDropIndicatorOffsetRtl :
662 kDropIndicatorOffsetLtr);
663
664 SchedulePaint();
665 return DragDropTypes::DRAG_MOVE;
666 }
667
668 void BrowserActionsContainer::OnDragExited() {
669 drop_indicator_position_ = -1;
670 SchedulePaint();
671 }
672
673 int BrowserActionsContainer::OnPerformDrop(
674 const views::DropTargetEvent& event) {
675 BrowserActionDragData data;
676 if (!data.Read(event.GetData()))
677 return DragDropTypes::DRAG_NONE;
678
679 // Make sure we have the same view as we started with.
680 DCHECK(browser_action_views_[data.index()]->button()->extension()->id() ==
681 data.id());
682
683 Extension* dragging =
684 browser_action_views_[data.index()]->button()->extension();
685
686 int target_x = drop_indicator_position_;
687
688 size_t i = 0;
689 for (; i < browser_action_views_.size(); ++i) {
690 int view_x =
691 browser_action_views_[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).x();
692 if (!browser_action_views_[i]->IsVisible() ||
693 (UILayoutIsRightToLeft() ? view_x < target_x : view_x >= target_x)) {
694 // We have reached the end of the visible icons or found one that has a
695 // higher x position than the drop point.
696 break;
697 }
698 }
699
700 // |i| now points to the item to the right of the drop indicator*, which is
701 // correct when dragging an icon to the left. When dragging to the right,
702 // however, we want the icon being dragged to get the index of the item to
703 // the left of the drop indicator, so we subtract one.
704 // * Well, it can also point to the end, but not when dragging to the left. :)
705 if (i > data.index())
706 --i;
707
708 model_->MoveBrowserAction(dragging, i);
709
710 OnDragExited(); // Perform clean up after dragging.
711 return DragDropTypes::DRAG_MOVE;
712 }
713
575 void BrowserActionsContainer::Observe(NotificationType type, 714 void BrowserActionsContainer::Observe(NotificationType type,
576 const NotificationSource& source, 715 const NotificationSource& source,
577 const NotificationDetails& details) { 716 const NotificationDetails& details) {
578 switch (type.value) { 717 switch (type.value) {
579 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE: 718 case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
580 // If we aren't the host of the popup, then disregard the notification. 719 // If we aren't the host of the popup, then disregard the notification.
581 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details) 720 if (!popup_ || Details<ExtensionHost>(popup_->host()) != details)
582 return; 721 return;
583 722
584 HidePopup(); 723 HidePopup();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 } 771 }
633 772
634 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) { 773 void BrowserActionsContainer::RunMenu(View* source, const gfx::Point& pt) {
635 if (source == chevron_) { 774 if (source == chevron_) {
636 overflow_menu_.reset(new BrowserActionOverflowMenuController( 775 overflow_menu_.reset(new BrowserActionOverflowMenuController(
637 this, chevron_, browser_action_views_, VisibleBrowserActions())); 776 this, chevron_, browser_action_views_, VisibleBrowserActions()));
638 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow()); 777 overflow_menu_->RunMenu(GetWindow()->GetNativeWindow());
639 } 778 }
640 } 779 }
641 780
642 int BrowserActionsContainer::ClampToNearestIconCount(int pixelWidth) const { 781 void BrowserActionsContainer::WriteDragData(
782 View* sender, int press_x, int press_y, OSExchangeData* data) {
783 DCHECK(data);
784
785 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
786 if (browser_action_views_[i]->button() == sender) {
787 BrowserActionDragData drag_data(
788 browser_action_views_[i]->button()->extension()->id(), i);
789 drag_data.Write(profile_, data);
790 break;
791 }
792 }
793 }
794
795 int BrowserActionsContainer::GetDragOperations(View* sender, int x, int y) {
796 return DragDropTypes::DRAG_MOVE;
797 }
798
799 bool BrowserActionsContainer::CanStartDrag(
800 View* sender, int press_x, int press_y, int x, int y) {
801 return true;
802 }
803
804 int BrowserActionsContainer::ClampToNearestIconCount(
805 int pixelWidth, bool allow_shrink_to_minimum) const {
643 // Calculate the width of one icon. 806 // Calculate the width of one icon.
644 int icon_width = (kButtonSize + kBrowserActionButtonPadding); 807 int icon_width = (kButtonSize + kBrowserActionButtonPadding);
645 808
646 // Calculate pixel count for the area not used by the icons. 809 // Calculate pixel count for the area not used by the icons.
647 int extras = WidthOfNonIconArea(); 810 int extras = WidthOfNonIconArea();
648 811
649 size_t icon_count = 0u; 812 size_t icon_count = 0u;
650 if (pixelWidth >= 0) { 813 if (pixelWidth >= 0) {
651 // Caller wants to know how many icons fit within a given space so we start 814 // Caller wants to know how many icons fit within a given space so we start
652 // by subtracting the padding, gripper and dividers. 815 // by subtracting the padding, gripper and dividers.
653 int icon_area = pixelWidth - extras; 816 int icon_area = pixelWidth - extras;
654 icon_area = std::max(0, icon_area); 817 icon_area = std::max(0, icon_area);
655 818
656 // Make sure we never throw an icon into the chevron menu just because 819 // Make sure we never throw an icon into the chevron menu just because
657 // there isn't enough enough space for the invisible padding around buttons. 820 // there isn't enough enough space for the invisible padding around buttons.
658 icon_area += kBrowserActionButtonPadding - 1; 821 icon_area += kBrowserActionButtonPadding - 1;
659 822
660 // Count the number of icons that fit within that area. 823 // Count the number of icons that fit within that area.
661 icon_count = icon_area / icon_width; 824 icon_count = icon_area / icon_width;
662 825
663 // No use allowing more than what we have. 826 if (icon_count == 0 && allow_shrink_to_minimum) {
664 if (icon_count > browser_action_views_.size()) 827 extras = ContainerMinSize(); // Allow very narrow width if no icons.
828 } else if (icon_count > browser_action_views_.size()) {
829 // No use allowing more than what we have.
665 icon_count = browser_action_views_.size(); 830 icon_count = browser_action_views_.size();
666 else if (icon_count == 0) 831 }
667 extras = ContainerMinSize(); // Allow very narrow width if no icons.
668 } else { 832 } else {
669 // A negative |pixels| count indicates caller wants to know the max width 833 // A negative |pixels| count indicates caller wants to know the max width
670 // that fits all icons; 834 // that fits all icons;
671 icon_count = browser_action_views_.size(); 835 icon_count = browser_action_views_.size();
672 } 836 }
673 837
674 int returning = extras + (icon_count * icon_width); 838 return extras + (icon_count * icon_width);
675 return returning;
676 } 839 }
677 840
678 void BrowserActionsContainer::BrowserActionAdded(Extension* extension, 841 void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
679 int index) { 842 int index) {
680 #if defined(DEBUG) 843 #if defined(DEBUG)
681 for (size_t i = 0; i < browser_action_views_.size(); ++i) { 844 for (size_t i = 0; i < browser_action_views_.size(); ++i) {
682 DCHECK(browser_action_views_[i]->button()->extension() != extension) << 845 DCHECK(browser_action_views_[i]->button()->extension() != extension) <<
683 "Asked to add a browser action view for an extension that already " 846 "Asked to add a browser action view for an extension that already "
684 "exists."; 847 "exists.";
685 } 848 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 901
739 // For details on why we do the following see the class comments in the 902 // For details on why we do the following see the class comments in the
740 // header. 903 // header.
741 904
742 // Calculate the target size we'll animate to (end state). This might be 905 // Calculate the target size we'll animate to (end state). This might be
743 // the same size (if the icon we are removing is in the overflow bucket 906 // the same size (if the icon we are removing is in the overflow bucket
744 // and there are other icons there). We don't decrement visible_actions 907 // and there are other icons there). We don't decrement visible_actions
745 // because we want the container to stay the same size (clamping will take 908 // because we want the container to stay the same size (clamping will take
746 // care of shrinking the container if there aren't enough icons to show). 909 // care of shrinking the container if there aren't enough icons to show).
747 animation_target_size_ = 910 animation_target_size_ =
748 ClampToNearestIconCount(IconCountToWidth(visible_actions)); 911 ClampToNearestIconCount(IconCountToWidth(visible_actions), true);
749 912
750 // Animate! 913 // Animate!
751 resize_animation_->Reset(); 914 resize_animation_->Reset();
752 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT); 915 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
753 resize_animation_->Show(); 916 resize_animation_->Show();
754 return; 917 return;
755 } 918 }
756 } 919 }
757 } 920 }
758 921
922 void BrowserActionsContainer::BrowserActionMoved(Extension* extension,
923 int index) {
924 DCHECK(index >= 0 && index < static_cast<int>(browser_action_views_.size()));
925
926 DeleteBrowserActionViews();
927 CreateBrowserActionViews();
928 Layout();
929 }
930
759 int BrowserActionsContainer::WidthOfNonIconArea() const { 931 int BrowserActionsContainer::WidthOfNonIconArea() const {
760 int chevron_size = (chevron_->IsVisible()) ? 932 int chevron_size = (chevron_->IsVisible()) ?
761 chevron_->GetPreferredSize().width() : 0; 933 chevron_->GetPreferredSize().width() : 0;
762 return resize_gripper_->GetPreferredSize().width() + kHorizontalPadding + 934 int padding = UILayoutIsRightToLeft() ? kHorizontalPaddingRtl :
935 kHorizontalPadding;
936 return resize_gripper_->GetPreferredSize().width() + padding +
763 chevron_size + kChevronRightMargin + kDividerHorizontalMargin; 937 chevron_size + kChevronRightMargin + kDividerHorizontalMargin;
764 } 938 }
765 939
766 int BrowserActionsContainer::IconCountToWidth(int icons) const { 940 int BrowserActionsContainer::IconCountToWidth(int icons) const {
767 DCHECK(icons >= 0); 941 DCHECK(icons >= 0);
768 if (icons == 0) 942 if (icons == 0)
769 return ContainerMinSize(); 943 return ContainerMinSize();
770 944
771 int icon_width = kButtonSize + kBrowserActionButtonPadding; 945 int icon_width = kButtonSize + kBrowserActionButtonPadding;
772 946
(...skipping 18 matching lines...) Expand all
791 if (!done_resizing) { 965 if (!done_resizing) {
792 resize_amount_ = resize_amount; 966 resize_amount_ = resize_amount;
793 OnBrowserActionVisibilityChanged(); 967 OnBrowserActionVisibilityChanged();
794 } else { 968 } else {
795 // For details on why we do the following see the class comments in the 969 // For details on why we do the following see the class comments in the
796 // header. 970 // header.
797 971
798 // Clamp lower limit to 0 and upper limit to the amount that allows enough 972 // Clamp lower limit to 0 and upper limit to the amount that allows enough
799 // room for all icons to show. 973 // room for all icons to show.
800 int new_width = std::max(0, container_size_.width() - resize_amount); 974 int new_width = std::max(0, container_size_.width() - resize_amount);
801 int max_width = ClampToNearestIconCount(-1); 975 int max_width = ClampToNearestIconCount(-1, false);
802 new_width = std::min(new_width, max_width); 976 new_width = std::min(new_width, max_width);
803 977
804 // Up until now we've only been modifying the resize_amount, but now it is 978 // Up until now we've only been modifying the resize_amount, but now it is
805 // time to set the container size to the size we have resized to, but then 979 // time to set the container size to the size we have resized to, but then
806 // animate to the nearest icon count size (or down to min size if no icon). 980 // animate to the nearest icon count size (or down to min size if no icon).
807 container_size_.set_width(new_width); 981 container_size_.set_width(new_width);
808 animation_target_size_ = ClampToNearestIconCount(new_width); 982 animation_target_size_ = ClampToNearestIconCount(new_width, true);
809 resize_animation_->Reset(); 983 resize_animation_->Reset();
810 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT); 984 resize_animation_->SetTweenType(SlideAnimation::EASE_OUT);
811 resize_animation_->Show(); 985 resize_animation_->Show();
812 } 986 }
813 } 987 }
814 988
815 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) { 989 void BrowserActionsContainer::AnimationProgressed(const Animation* animation) {
816 DCHECK(animation == resize_animation_.get()); 990 DCHECK(animation == resize_animation_.get());
817 991
818 double e = resize_animation_->GetCurrentValue(); 992 double e = resize_animation_->GetCurrentValue();
819 int difference = container_size_.width() - animation_target_size_; 993 int difference = container_size_.width() - animation_target_size_;
820 994
821 resize_amount_ = static_cast<int>(e * difference); 995 resize_amount_ = static_cast<int>(e * difference);
822 996
823 OnBrowserActionVisibilityChanged(); 997 OnBrowserActionVisibilityChanged();
824 } 998 }
825 999
826 void BrowserActionsContainer::AnimationEnded(const Animation* animation) { 1000 void BrowserActionsContainer::AnimationEnded(const Animation* animation) {
827 container_size_.set_width(animation_target_size_); 1001 container_size_.set_width(animation_target_size_);
828 animation_target_size_ = 0; 1002 animation_target_size_ = 0;
829 resize_amount_ = 0; 1003 resize_amount_ = 0;
830 OnBrowserActionVisibilityChanged(); 1004 OnBrowserActionVisibilityChanged();
831 suppress_chevron_ = false; 1005 suppress_chevron_ = false;
832 1006
833 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth, 1007 profile_->GetPrefs()->SetInteger(prefs::kBrowserActionContainerWidth,
834 container_size_.width()); 1008 container_size_.width());
835 } 1009 }
OLDNEW
« no previous file with comments | « chrome/browser/views/browser_actions_container.h ('k') | chrome/browser/views/extensions/browser_action_drag_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698