| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" | 5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "chrome/browser/extensions/extension_action_manager.h" | 9 #include "chrome/browser/extensions/extension_action_manager.h" |
| 10 #include "chrome/browser/extensions/extension_util.h" | 10 #include "chrome/browser/extensions/extension_util.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 #include "ui/views/controls/button/menu_button.h" | 43 #include "ui/views/controls/button/menu_button.h" |
| 44 #include "ui/views/controls/resize_area.h" | 44 #include "ui/views/controls/resize_area.h" |
| 45 #include "ui/views/metrics.h" | 45 #include "ui/views/metrics.h" |
| 46 #include "ui/views/painter.h" | 46 #include "ui/views/painter.h" |
| 47 #include "ui/views/widget/widget.h" | 47 #include "ui/views/widget/widget.h" |
| 48 | 48 |
| 49 using extensions::Extension; | 49 using extensions::Extension; |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 | 52 |
| 53 // Horizontal spacing between most items in the container, as well as after the | |
| 54 // last item or chevron (if visible). | |
| 55 const int kItemSpacing = ToolbarView::kStandardSpacing; | |
| 56 | |
| 57 // Horizontal spacing before the chevron (if visible). | 53 // Horizontal spacing before the chevron (if visible). |
| 58 const int kChevronSpacing = kItemSpacing - 2; | 54 const int kChevronSpacing = ToolbarView::kStandardSpacing - 2; |
| 59 | |
| 60 // The maximum number of icons to show per row when in overflow mode (showing | |
| 61 // icons in the application menu). | |
| 62 // TODO(devlin): Compute the right number of icons to show, depending on the | |
| 63 // menu width. | |
| 64 #if defined(OS_LINUX) | |
| 65 const int kIconsPerMenuRow = 8; // The menu on Linux is wider. | |
| 66 #else | |
| 67 const int kIconsPerMenuRow = 7; | |
| 68 #endif | |
| 69 | 55 |
| 70 // A version of MenuButton with almost empty insets to fit properly on the | 56 // A version of MenuButton with almost empty insets to fit properly on the |
| 71 // toolbar. | 57 // toolbar. |
| 72 class ChevronMenuButton : public views::MenuButton { | 58 class ChevronMenuButton : public views::MenuButton { |
| 73 public: | 59 public: |
| 74 ChevronMenuButton(views::ButtonListener* listener, | 60 ChevronMenuButton(views::ButtonListener* listener, |
| 75 const base::string16& text, | 61 const base::string16& text, |
| 76 views::MenuButtonListener* menu_button_listener, | 62 views::MenuButtonListener* menu_button_listener, |
| 77 bool show_menu_marker) | 63 bool show_menu_marker) |
| 78 : views::MenuButton(listener, | 64 : views::MenuButton(listener, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 99 |
| 114 BrowserActionsContainer::DropPosition::DropPosition( | 100 BrowserActionsContainer::DropPosition::DropPosition( |
| 115 size_t row, size_t icon_in_row) | 101 size_t row, size_t icon_in_row) |
| 116 : row(row), icon_in_row(icon_in_row) { | 102 : row(row), icon_in_row(icon_in_row) { |
| 117 } | 103 } |
| 118 | 104 |
| 119 //////////////////////////////////////////////////////////////////////////////// | 105 //////////////////////////////////////////////////////////////////////////////// |
| 120 // BrowserActionsContainer | 106 // BrowserActionsContainer |
| 121 | 107 |
| 122 // static | 108 // static |
| 109 int BrowserActionsContainer::icons_per_overflow_menu_row_ = 1; |
| 110 |
| 111 // static |
| 112 const int BrowserActionsContainer::kItemSpacing = ToolbarView::kStandardSpacing; |
| 113 |
| 114 // static |
| 123 bool BrowserActionsContainer::disable_animations_during_testing_ = false; | 115 bool BrowserActionsContainer::disable_animations_during_testing_ = false; |
| 124 | 116 |
| 125 BrowserActionsContainer::BrowserActionsContainer( | 117 BrowserActionsContainer::BrowserActionsContainer( |
| 126 Browser* browser, | 118 Browser* browser, |
| 127 View* owner_view, | 119 View* owner_view, |
| 128 BrowserActionsContainer* main_container) | 120 BrowserActionsContainer* main_container) |
| 129 : initialized_(false), | 121 : initialized_(false), |
| 130 profile_(browser->profile()), | 122 profile_(browser->profile()), |
| 131 browser_(browser), | 123 browser_(browser), |
| 132 owner_view_(owner_view), | 124 owner_view_(owner_view), |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 329 |
| 338 // If there are no actions to show, or we are in overflow mode and the main | 330 // If there are no actions to show, or we are in overflow mode and the main |
| 339 // container is already showing them all, then no further work is required. | 331 // container is already showing them all, then no further work is required. |
| 340 if (icon_count == 0) | 332 if (icon_count == 0) |
| 341 return gfx::Size(); | 333 return gfx::Size(); |
| 342 | 334 |
| 343 if (in_overflow_mode()) { | 335 if (in_overflow_mode()) { |
| 344 // When in overflow, y is multiline, so the pixel count is IconHeight() | 336 // When in overflow, y is multiline, so the pixel count is IconHeight() |
| 345 // times the number of rows needed. | 337 // times the number of rows needed. |
| 346 return gfx::Size( | 338 return gfx::Size( |
| 347 IconCountToWidth(kIconsPerMenuRow, false), | 339 IconCountToWidth(icons_per_overflow_menu_row_, false), |
| 348 (((icon_count - 1) / kIconsPerMenuRow) + 1) * IconHeight()); | 340 (((icon_count - 1) / icons_per_overflow_menu_row_) + 1) * IconHeight()); |
| 349 } | 341 } |
| 350 | 342 |
| 351 // We calculate the size of the view by taking the current width and | 343 // We calculate the size of the view by taking the current width and |
| 352 // subtracting resize_amount_ (the latter represents how far the user is | 344 // subtracting resize_amount_ (the latter represents how far the user is |
| 353 // resizing the view or, if animating the snapping, how far to animate it). | 345 // resizing the view or, if animating the snapping, how far to animate it). |
| 354 // But we also clamp it to a minimum size and the maximum size, so that the | 346 // But we also clamp it to a minimum size and the maximum size, so that the |
| 355 // container can never shrink too far or take up more space than it needs. | 347 // container can never shrink too far or take up more space than it needs. |
| 356 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). | 348 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). |
| 357 int preferred_width = std::min( | 349 int preferred_width = std::min( |
| 358 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), | 350 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), |
| 359 IconCountToWidth(-1, false)); | 351 IconCountToWidth(-1, false)); |
| 360 return gfx::Size(preferred_width, IconHeight()); | 352 return gfx::Size(preferred_width, IconHeight()); |
| 361 } | 353 } |
| 362 | 354 |
| 355 int BrowserActionsContainer::GetHeightForWidth(int width) const { |
| 356 if (in_overflow_mode()) |
| 357 icons_per_overflow_menu_row_ = (width - kItemSpacing) / IconWidth(true); |
| 358 return GetPreferredSize().height(); |
| 359 } |
| 360 |
| 363 gfx::Size BrowserActionsContainer::GetMinimumSize() const { | 361 gfx::Size BrowserActionsContainer::GetMinimumSize() const { |
| 364 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1, false)); | 362 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1, false)); |
| 365 return gfx::Size(min_width, IconHeight()); | 363 return gfx::Size(min_width, IconHeight()); |
| 366 } | 364 } |
| 367 | 365 |
| 368 void BrowserActionsContainer::Layout() { | 366 void BrowserActionsContainer::Layout() { |
| 369 if (browser_action_views_.empty()) { | 367 if (browser_action_views_.empty()) { |
| 370 SetVisible(false); | 368 SetVisible(false); |
| 371 return; | 369 return; |
| 372 } | 370 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 398 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { | 396 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { |
| 399 // Ensure that any browser actions shown in the main view are hidden in | 397 // Ensure that any browser actions shown in the main view are hidden in |
| 400 // the overflow view. | 398 // the overflow view. |
| 401 browser_action_views_[i]->SetVisible(false); | 399 browser_action_views_[i]->SetVisible(false); |
| 402 } | 400 } |
| 403 | 401 |
| 404 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); | 402 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); |
| 405 i < browser_action_views_.size(); ++i) { | 403 i < browser_action_views_.size(); ++i) { |
| 406 BrowserActionView* view = browser_action_views_[i]; | 404 BrowserActionView* view = browser_action_views_[i]; |
| 407 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); | 405 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); |
| 408 int row_index = static_cast<int>(index) / kIconsPerMenuRow; | 406 int row_index = static_cast<int>(index) / icons_per_overflow_menu_row_; |
| 409 int x = kItemSpacing + (index * IconWidth(true)) - | 407 int x = kItemSpacing + (index * IconWidth(true)) - |
| 410 (row_index * IconWidth(true) * kIconsPerMenuRow); | 408 (row_index * IconWidth(true) * icons_per_overflow_menu_row_); |
| 411 gfx::Rect rect_bounds( | 409 gfx::Rect rect_bounds( |
| 412 x, IconHeight() * row_index, icon_width, IconHeight()); | 410 x, IconHeight() * row_index, icon_width, IconHeight()); |
| 413 view->SetBoundsRect(rect_bounds); | 411 view->SetBoundsRect(rect_bounds); |
| 414 view->SetVisible(true); | 412 view->SetVisible(true); |
| 415 } | 413 } |
| 416 } else { | 414 } else { |
| 417 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); | 415 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); |
| 418 it < browser_action_views_.end(); ++it) { | 416 it < browser_action_views_.end(); ++it) { |
| 419 BrowserActionView* view = *it; | 417 BrowserActionView* view = *it; |
| 420 int x = ToolbarView::kStandardSpacing + | 418 int x = ToolbarView::kStandardSpacing + |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 kItemSpacing) / IconWidth(true); | 493 kItemSpacing) / IconWidth(true); |
| 496 | 494 |
| 497 // We need to figure out how many icons are visible on the relevant row. | 495 // We need to figure out how many icons are visible on the relevant row. |
| 498 // In the main container, this will just be the visible actions. | 496 // In the main container, this will just be the visible actions. |
| 499 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); | 497 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
| 500 if (in_overflow_mode()) { | 498 if (in_overflow_mode()) { |
| 501 // If this is the final row of the overflow, then this is the remainder of | 499 // If this is the final row of the overflow, then this is the remainder of |
| 502 // visible icons. Otherwise, it's a full row (kIconsPerRow). | 500 // visible icons. Otherwise, it's a full row (kIconsPerRow). |
| 503 visible_icons_on_row = | 501 visible_icons_on_row = |
| 504 row_index == | 502 row_index == |
| 505 static_cast<size_t>(visible_icons_on_row / kIconsPerMenuRow) ? | 503 static_cast<size_t>(visible_icons_on_row / |
| 506 visible_icons_on_row % kIconsPerMenuRow : | 504 icons_per_overflow_menu_row_) ? |
| 507 kIconsPerMenuRow; | 505 visible_icons_on_row % icons_per_overflow_menu_row_ : |
| 506 icons_per_overflow_menu_row_; |
| 508 } | 507 } |
| 509 | 508 |
| 510 // Because the user can drag outside the container bounds, we need to clamp to | 509 // Because the user can drag outside the container bounds, we need to clamp to |
| 511 // the valid range. Note that the maximum allowable value is (num icons), not | 510 // the valid range. Note that the maximum allowable value is (num icons), not |
| 512 // (num icons - 1), because we represent the indicator being past the last | 511 // (num icons - 1), because we represent the indicator being past the last |
| 513 // icon as being "before the (last + 1) icon". | 512 // icon as being "before the (last + 1) icon". |
| 514 size_t before_icon_in_row = | 513 size_t before_icon_in_row = |
| 515 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); | 514 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); |
| 516 | 515 |
| 517 if (!drop_position_.get() || | 516 if (!drop_position_.get() || |
| (...skipping 16 matching lines...) Expand all Loading... |
| 534 const ui::DropTargetEvent& event) { | 533 const ui::DropTargetEvent& event) { |
| 535 BrowserActionDragData data; | 534 BrowserActionDragData data; |
| 536 if (!data.Read(event.data())) | 535 if (!data.Read(event.data())) |
| 537 return ui::DragDropTypes::DRAG_NONE; | 536 return ui::DragDropTypes::DRAG_NONE; |
| 538 | 537 |
| 539 // Make sure we have the same view as we started with. | 538 // Make sure we have the same view as we started with. |
| 540 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), | 539 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), |
| 541 data.id()); | 540 data.id()); |
| 542 DCHECK(model_); | 541 DCHECK(model_); |
| 543 | 542 |
| 544 size_t i = | 543 size_t i = drop_position_->row * icons_per_overflow_menu_row_ + |
| 545 drop_position_->row * kIconsPerMenuRow + drop_position_->icon_in_row; | 544 drop_position_->icon_in_row; |
| 546 if (in_overflow_mode()) | 545 if (in_overflow_mode()) |
| 547 i += GetFirstVisibleIconIndex(); | 546 i += GetFirstVisibleIconIndex(); |
| 548 // |i| now points to the item to the right of the drop indicator*, which is | 547 // |i| now points to the item to the right of the drop indicator*, which is |
| 549 // correct when dragging an icon to the left. When dragging to the right, | 548 // correct when dragging an icon to the left. When dragging to the right, |
| 550 // however, we want the icon being dragged to get the index of the item to | 549 // however, we want the icon being dragged to get the index of the item to |
| 551 // the left of the drop indicator, so we subtract one. | 550 // the left of the drop indicator, so we subtract one. |
| 552 // * Well, it can also point to the end, but not when dragging to the left. :) | 551 // * Well, it can also point to the end, but not when dragging to the left. :) |
| 553 if (i > data.index()) | 552 if (i > data.index()) |
| 554 --i; | 553 --i; |
| 555 | 554 |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 int BrowserActionsContainer::IconCountToWidth(int icons, | 1037 int BrowserActionsContainer::IconCountToWidth(int icons, |
| 1039 bool display_chevron) const { | 1038 bool display_chevron) const { |
| 1040 if (icons < 0) | 1039 if (icons < 0) |
| 1041 icons = browser_action_views_.size(); | 1040 icons = browser_action_views_.size(); |
| 1042 if ((icons == 0) && !display_chevron) | 1041 if ((icons == 0) && !display_chevron) |
| 1043 return ToolbarView::kStandardSpacing; | 1042 return ToolbarView::kStandardSpacing; |
| 1044 int icons_size = | 1043 int icons_size = |
| 1045 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); | 1044 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); |
| 1046 int chevron_size = chevron_ && display_chevron ? | 1045 int chevron_size = chevron_ && display_chevron ? |
| 1047 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; | 1046 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; |
| 1048 return ToolbarView::kStandardSpacing + icons_size + chevron_size + | 1047 // In overflow mode, our padding is to use item spacing on either end (just so |
| 1049 ToolbarView::kStandardSpacing; | 1048 // we can see the drop indicator). Otherwise we use the standard toolbar |
| 1049 // spacing. |
| 1050 // Note: These are actually the same thing, but, on the offchance one |
| 1051 // changes, let's get it right. |
| 1052 int padding = |
| 1053 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); |
| 1054 return icons_size + chevron_size + padding; |
| 1050 } | 1055 } |
| 1051 | 1056 |
| 1052 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { | 1057 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
| 1053 // Check for widths large enough to show the entire icon set. | 1058 // Check for widths large enough to show the entire icon set. |
| 1054 if (pixels >= IconCountToWidth(-1, false)) | 1059 if (pixels >= IconCountToWidth(-1, false)) |
| 1055 return browser_action_views_.size(); | 1060 return browser_action_views_.size(); |
| 1056 | 1061 |
| 1057 // We reserve space for the padding on either side of the toolbar... | 1062 // We reserve space for the padding on either side of the toolbar... |
| 1058 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); | 1063 int available_space = pixels - (ToolbarView::kStandardSpacing * 2); |
| 1059 // ... and, if the chevron is enabled, the chevron. | 1064 // ... and, if the chevron is enabled, the chevron. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 if (initialized_ && profile_->IsOffTheRecord()) { | 1132 if (initialized_ && profile_->IsOffTheRecord()) { |
| 1128 main_displayed = in_overflow_mode() ? | 1133 main_displayed = in_overflow_mode() ? |
| 1129 main_container_->VisibleBrowserActionsAfterAnimation() : | 1134 main_container_->VisibleBrowserActionsAfterAnimation() : |
| 1130 VisibleBrowserActionsAfterAnimation(); | 1135 VisibleBrowserActionsAfterAnimation(); |
| 1131 } | 1136 } |
| 1132 | 1137 |
| 1133 // The overflow displays any (displayable) icons not shown by the main bar. | 1138 // The overflow displays any (displayable) icons not shown by the main bar. |
| 1134 return in_overflow_mode() ? | 1139 return in_overflow_mode() ? |
| 1135 displayable_icon_count - main_displayed : main_displayed; | 1140 displayable_icon_count - main_displayed : main_displayed; |
| 1136 } | 1141 } |
| OLD | NEW |