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 : profile_(browser->profile()), | 121 : profile_(browser->profile()), |
130 browser_(browser), | 122 browser_(browser), |
131 owner_view_(owner_view), | 123 owner_view_(owner_view), |
132 main_container_(main_container), | 124 main_container_(main_container), |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 | 319 |
328 // If there are no actions to show, or we are in overflow mode and the main | 320 // If there are no actions to show, or we are in overflow mode and the main |
329 // container is already showing them all, then no further work is required. | 321 // container is already showing them all, then no further work is required. |
330 if (icon_count == 0) | 322 if (icon_count == 0) |
331 return gfx::Size(); | 323 return gfx::Size(); |
332 | 324 |
333 if (in_overflow_mode()) { | 325 if (in_overflow_mode()) { |
334 // When in overflow, y is multiline, so the pixel count is IconHeight() | 326 // When in overflow, y is multiline, so the pixel count is IconHeight() |
335 // times the number of rows needed. | 327 // times the number of rows needed. |
336 return gfx::Size( | 328 return gfx::Size( |
337 IconCountToWidth(kIconsPerMenuRow, false), | 329 IconCountToWidth(icons_per_overflow_menu_row_, false), |
338 (((icon_count - 1) / kIconsPerMenuRow) + 1) * IconHeight()); | 330 (((icon_count - 1) / icons_per_overflow_menu_row_) + 1) * IconHeight()); |
339 } | 331 } |
340 | 332 |
341 // We calculate the size of the view by taking the current width and | 333 // We calculate the size of the view by taking the current width and |
342 // subtracting resize_amount_ (the latter represents how far the user is | 334 // subtracting resize_amount_ (the latter represents how far the user is |
343 // resizing the view or, if animating the snapping, how far to animate it). | 335 // resizing the view or, if animating the snapping, how far to animate it). |
344 // But we also clamp it to a minimum size and the maximum size, so that the | 336 // But we also clamp it to a minimum size and the maximum size, so that the |
345 // container can never shrink too far or take up more space than it needs. | 337 // container can never shrink too far or take up more space than it needs. |
346 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). | 338 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). |
347 int preferred_width = std::min( | 339 int preferred_width = std::min( |
348 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), | 340 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), |
349 IconCountToWidth(-1, false)); | 341 IconCountToWidth(-1, false)); |
350 return gfx::Size(preferred_width, IconHeight()); | 342 return gfx::Size(preferred_width, IconHeight()); |
351 } | 343 } |
352 | 344 |
| 345 int BrowserActionsContainer::GetHeightForWidth(int width) const { |
| 346 if (in_overflow_mode()) |
| 347 icons_per_overflow_menu_row_ = (width - kItemSpacing) / IconWidth(true); |
| 348 return GetPreferredSize().height(); |
| 349 } |
| 350 |
353 gfx::Size BrowserActionsContainer::GetMinimumSize() const { | 351 gfx::Size BrowserActionsContainer::GetMinimumSize() const { |
354 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1, false)); | 352 int min_width = std::min(MinimumNonemptyWidth(), IconCountToWidth(-1, false)); |
355 return gfx::Size(min_width, IconHeight()); | 353 return gfx::Size(min_width, IconHeight()); |
356 } | 354 } |
357 | 355 |
358 void BrowserActionsContainer::Layout() { | 356 void BrowserActionsContainer::Layout() { |
359 if (browser_action_views_.empty()) { | 357 if (browser_action_views_.empty()) { |
360 SetVisible(false); | 358 SetVisible(false); |
361 return; | 359 return; |
362 } | 360 } |
(...skipping 25 matching lines...) Expand all Loading... |
388 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { | 386 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { |
389 // Ensure that any browser actions shown in the main view are hidden in | 387 // Ensure that any browser actions shown in the main view are hidden in |
390 // the overflow view. | 388 // the overflow view. |
391 browser_action_views_[i]->SetVisible(false); | 389 browser_action_views_[i]->SetVisible(false); |
392 } | 390 } |
393 | 391 |
394 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); | 392 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); |
395 i < browser_action_views_.size(); ++i) { | 393 i < browser_action_views_.size(); ++i) { |
396 BrowserActionView* view = browser_action_views_[i]; | 394 BrowserActionView* view = browser_action_views_[i]; |
397 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); | 395 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); |
398 int row_index = static_cast<int>(index) / kIconsPerMenuRow; | 396 int row_index = static_cast<int>(index) / icons_per_overflow_menu_row_; |
399 int x = kItemSpacing + (index * IconWidth(true)) - | 397 int x = kItemSpacing + (index * IconWidth(true)) - |
400 (row_index * IconWidth(true) * kIconsPerMenuRow); | 398 (row_index * IconWidth(true) * icons_per_overflow_menu_row_); |
401 gfx::Rect rect_bounds( | 399 gfx::Rect rect_bounds( |
402 x, IconHeight() * row_index, icon_width, IconHeight()); | 400 x, IconHeight() * row_index, icon_width, IconHeight()); |
403 view->SetBoundsRect(rect_bounds); | 401 view->SetBoundsRect(rect_bounds); |
404 view->SetVisible(true); | 402 view->SetVisible(true); |
405 } | 403 } |
406 } else { | 404 } else { |
407 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); | 405 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); |
408 it < browser_action_views_.end(); ++it) { | 406 it < browser_action_views_.end(); ++it) { |
409 BrowserActionView* view = *it; | 407 BrowserActionView* view = *it; |
410 int x = ToolbarView::kStandardSpacing + | 408 int x = ToolbarView::kStandardSpacing + |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 kItemSpacing) / IconWidth(true); | 483 kItemSpacing) / IconWidth(true); |
486 | 484 |
487 // We need to figure out how many icons are visible on the relevant row. | 485 // We need to figure out how many icons are visible on the relevant row. |
488 // In the main container, this will just be the visible actions. | 486 // In the main container, this will just be the visible actions. |
489 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); | 487 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
490 if (in_overflow_mode()) { | 488 if (in_overflow_mode()) { |
491 // If this is the final row of the overflow, then this is the remainder of | 489 // If this is the final row of the overflow, then this is the remainder of |
492 // visible icons. Otherwise, it's a full row (kIconsPerRow). | 490 // visible icons. Otherwise, it's a full row (kIconsPerRow). |
493 visible_icons_on_row = | 491 visible_icons_on_row = |
494 row_index == | 492 row_index == |
495 static_cast<size_t>(visible_icons_on_row / kIconsPerMenuRow) ? | 493 static_cast<size_t>(visible_icons_on_row / |
496 visible_icons_on_row % kIconsPerMenuRow : | 494 icons_per_overflow_menu_row_) ? |
497 kIconsPerMenuRow; | 495 visible_icons_on_row % icons_per_overflow_menu_row_ : |
| 496 icons_per_overflow_menu_row_; |
498 } | 497 } |
499 | 498 |
500 // Because the user can drag outside the container bounds, we need to clamp to | 499 // Because the user can drag outside the container bounds, we need to clamp to |
501 // the valid range. Note that the maximum allowable value is (num icons), not | 500 // the valid range. Note that the maximum allowable value is (num icons), not |
502 // (num icons - 1), because we represent the indicator being past the last | 501 // (num icons - 1), because we represent the indicator being past the last |
503 // icon as being "before the (last + 1) icon". | 502 // icon as being "before the (last + 1) icon". |
504 size_t before_icon_in_row = | 503 size_t before_icon_in_row = |
505 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); | 504 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); |
506 | 505 |
507 if (!drop_position_.get() || | 506 if (!drop_position_.get() || |
(...skipping 16 matching lines...) Expand all Loading... |
524 const ui::DropTargetEvent& event) { | 523 const ui::DropTargetEvent& event) { |
525 BrowserActionDragData data; | 524 BrowserActionDragData data; |
526 if (!data.Read(event.data())) | 525 if (!data.Read(event.data())) |
527 return ui::DragDropTypes::DRAG_NONE; | 526 return ui::DragDropTypes::DRAG_NONE; |
528 | 527 |
529 // Make sure we have the same view as we started with. | 528 // Make sure we have the same view as we started with. |
530 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), | 529 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), |
531 data.id()); | 530 data.id()); |
532 DCHECK(model_); | 531 DCHECK(model_); |
533 | 532 |
534 size_t i = | 533 size_t i = drop_position_->row * icons_per_overflow_menu_row_ + |
535 drop_position_->row * kIconsPerMenuRow + drop_position_->icon_in_row; | 534 drop_position_->icon_in_row; |
536 if (in_overflow_mode()) | 535 if (in_overflow_mode()) |
537 i += GetFirstVisibleIconIndex(); | 536 i += GetFirstVisibleIconIndex(); |
538 // |i| now points to the item to the right of the drop indicator*, which is | 537 // |i| now points to the item to the right of the drop indicator*, which is |
539 // correct when dragging an icon to the left. When dragging to the right, | 538 // correct when dragging an icon to the left. When dragging to the right, |
540 // however, we want the icon being dragged to get the index of the item to | 539 // however, we want the icon being dragged to get the index of the item to |
541 // the left of the drop indicator, so we subtract one. | 540 // the left of the drop indicator, so we subtract one. |
542 // * Well, it can also point to the end, but not when dragging to the left. :) | 541 // * Well, it can also point to the end, but not when dragging to the left. :) |
543 if (i > data.index()) | 542 if (i > data.index()) |
544 --i; | 543 --i; |
545 | 544 |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 int BrowserActionsContainer::IconCountToWidth(int icons, | 1009 int BrowserActionsContainer::IconCountToWidth(int icons, |
1011 bool display_chevron) const { | 1010 bool display_chevron) const { |
1012 if (icons < 0) | 1011 if (icons < 0) |
1013 icons = browser_action_views_.size(); | 1012 icons = browser_action_views_.size(); |
1014 if ((icons == 0) && !display_chevron) | 1013 if ((icons == 0) && !display_chevron) |
1015 return ToolbarView::kStandardSpacing; | 1014 return ToolbarView::kStandardSpacing; |
1016 int icons_size = | 1015 int icons_size = |
1017 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); | 1016 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); |
1018 int chevron_size = chevron_ && display_chevron ? | 1017 int chevron_size = chevron_ && display_chevron ? |
1019 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; | 1018 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; |
1020 return ToolbarView::kStandardSpacing + icons_size + chevron_size + | 1019 // In overflow mode, our padding is to use item spacing on either end (just so |
1021 ToolbarView::kStandardSpacing; | 1020 // we can see the drop indicator). Otherwise we use the standard toolbar |
| 1021 // spacing. |
| 1022 // Note: These are actually the same thing, but, on the offchance one |
| 1023 // changes, let's get it right. |
| 1024 int padding = |
| 1025 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); |
| 1026 return icons_size + chevron_size + padding; |
1022 } | 1027 } |
1023 | 1028 |
1024 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { | 1029 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
1025 // Check for widths large enough to show the entire icon set. | 1030 // Check for widths large enough to show the entire icon set. |
1026 if (pixels >= IconCountToWidth(-1, false)) | 1031 if (pixels >= IconCountToWidth(-1, false)) |
1027 return browser_action_views_.size(); | 1032 return browser_action_views_.size(); |
1028 | 1033 |
1029 // We need to reserve space for the resize area, chevron, and the spacing on | 1034 // We need to reserve space for the resize area, chevron, and the spacing on |
1030 // either side of the chevron. | 1035 // either side of the chevron. |
1031 int available_space = pixels - ToolbarView::kStandardSpacing - | 1036 int available_space = pixels - ToolbarView::kStandardSpacing - |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 size_t absolute_model_size = | 1088 size_t absolute_model_size = |
1084 model_size == -1 ? extensions.size() : model_size; | 1089 model_size == -1 ? extensions.size() : model_size; |
1085 | 1090 |
1086 // The main container will try to show |model_size| icons, but reduce if there | 1091 // The main container will try to show |model_size| icons, but reduce if there |
1087 // aren't enough displayable icons to do so. | 1092 // aren't enough displayable icons to do so. |
1088 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); | 1093 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); |
1089 // The overflow will display the extras, if any. | 1094 // The overflow will display the extras, if any. |
1090 return in_overflow_mode() ? | 1095 return in_overflow_mode() ? |
1091 displayable_icon_count - main_displayed : main_displayed; | 1096 displayable_icon_count - main_displayed : main_displayed; |
1092 } | 1097 } |
OLD | NEW |