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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 #include "ui/views/controls/button/menu_button.h" | 42 #include "ui/views/controls/button/menu_button.h" |
43 #include "ui/views/controls/resize_area.h" | 43 #include "ui/views/controls/resize_area.h" |
44 #include "ui/views/metrics.h" | 44 #include "ui/views/metrics.h" |
45 #include "ui/views/painter.h" | 45 #include "ui/views/painter.h" |
46 #include "ui/views/widget/widget.h" | 46 #include "ui/views/widget/widget.h" |
47 | 47 |
48 using extensions::Extension; | 48 using extensions::Extension; |
49 | 49 |
50 namespace { | 50 namespace { |
51 | 51 |
52 // Horizontal spacing between most items in the container, as well as after the | |
53 // last item or chevron (if visible). | |
54 const int kItemSpacing = ToolbarView::kStandardSpacing; | |
55 | |
56 // Horizontal spacing before the chevron (if visible). | 52 // Horizontal spacing before the chevron (if visible). |
57 const int kChevronSpacing = kItemSpacing - 2; | 53 const int kChevronSpacing = ToolbarView::kStandardSpacing - 2; |
58 | |
59 // The maximum number of icons to show per row when in overflow mode (showing | |
60 // icons in the application menu). | |
61 // TODO(devlin): Compute the right number of icons to show, depending on the | |
62 // menu width. | |
63 #if defined(OS_LINUX) | |
64 const int kIconsPerMenuRow = 8; // The menu on Linux is wider. | |
65 #else | |
66 const int kIconsPerMenuRow = 7; | |
67 #endif | |
68 | 54 |
69 // A version of MenuButton with almost empty insets to fit properly on the | 55 // A version of MenuButton with almost empty insets to fit properly on the |
70 // toolbar. | 56 // toolbar. |
71 class ChevronMenuButton : public views::MenuButton { | 57 class ChevronMenuButton : public views::MenuButton { |
72 public: | 58 public: |
73 ChevronMenuButton(views::ButtonListener* listener, | 59 ChevronMenuButton(views::ButtonListener* listener, |
74 const base::string16& text, | 60 const base::string16& text, |
75 views::MenuButtonListener* menu_button_listener, | 61 views::MenuButtonListener* menu_button_listener, |
76 bool show_menu_marker) | 62 bool show_menu_marker) |
77 : views::MenuButton(listener, | 63 : views::MenuButton(listener, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 98 |
113 BrowserActionsContainer::DropPosition::DropPosition( | 99 BrowserActionsContainer::DropPosition::DropPosition( |
114 size_t row, size_t icon_in_row) | 100 size_t row, size_t icon_in_row) |
115 : row(row), icon_in_row(icon_in_row) { | 101 : row(row), icon_in_row(icon_in_row) { |
116 } | 102 } |
117 | 103 |
118 //////////////////////////////////////////////////////////////////////////////// | 104 //////////////////////////////////////////////////////////////////////////////// |
119 // BrowserActionsContainer | 105 // BrowserActionsContainer |
120 | 106 |
121 // static | 107 // static |
108 int BrowserActionsContainer::icons_per_menu_row = 1; | |
109 | |
110 // static | |
111 const int BrowserActionsContainer::kItemSpacing = ToolbarView::kStandardSpacing; | |
112 | |
113 // static | |
122 bool BrowserActionsContainer::disable_animations_during_testing_ = false; | 114 bool BrowserActionsContainer::disable_animations_during_testing_ = false; |
123 | 115 |
124 BrowserActionsContainer::BrowserActionsContainer( | 116 BrowserActionsContainer::BrowserActionsContainer( |
125 Browser* browser, | 117 Browser* browser, |
126 View* owner_view, | 118 View* owner_view, |
127 BrowserActionsContainer* main_container) | 119 BrowserActionsContainer* main_container) |
128 : profile_(browser->profile()), | 120 : profile_(browser->profile()), |
129 browser_(browser), | 121 browser_(browser), |
130 owner_view_(owner_view), | 122 owner_view_(owner_view), |
131 main_container_(main_container), | 123 main_container_(main_container), |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 | 310 |
319 // If there are no actions to show, or we are in overflow mode and the main | 311 // If there are no actions to show, or we are in overflow mode and the main |
320 // container is already showing them all, then no further work is required. | 312 // container is already showing them all, then no further work is required. |
321 if (icon_count == 0) | 313 if (icon_count == 0) |
322 return gfx::Size(); | 314 return gfx::Size(); |
323 | 315 |
324 if (in_overflow_mode()) { | 316 if (in_overflow_mode()) { |
325 // When in overflow, y is multiline, so the pixel count is IconHeight() | 317 // When in overflow, y is multiline, so the pixel count is IconHeight() |
326 // times the number of rows needed. | 318 // times the number of rows needed. |
327 return gfx::Size( | 319 return gfx::Size( |
328 IconCountToWidth(kIconsPerMenuRow, false), | 320 IconCountToWidth(icons_per_menu_row, false), |
329 (((icon_count - 1) / kIconsPerMenuRow) + 1) * IconHeight()); | 321 (((icon_count - 1) / icons_per_menu_row) + 1) * IconHeight()); |
330 } | 322 } |
331 | 323 |
332 // We calculate the size of the view by taking the current width and | 324 // We calculate the size of the view by taking the current width and |
333 // subtracting resize_amount_ (the latter represents how far the user is | 325 // subtracting resize_amount_ (the latter represents how far the user is |
334 // resizing the view or, if animating the snapping, how far to animate it). | 326 // resizing the view or, if animating the snapping, how far to animate it). |
335 // But we also clamp it to a minimum size and the maximum size, so that the | 327 // But we also clamp it to a minimum size and the maximum size, so that the |
336 // container can never shrink too far or take up more space than it needs. | 328 // container can never shrink too far or take up more space than it needs. |
337 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). | 329 // In other words: MinimumNonemptyWidth() < width() - resize < ClampTo(MAX). |
338 int preferred_width = std::min( | 330 int preferred_width = std::min( |
339 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), | 331 std::max(MinimumNonemptyWidth(), container_width_ - resize_amount_), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { | 371 i < main_container_->VisibleBrowserActionsAfterAnimation(); ++i) { |
380 // Ensure that any browser actions shown in the main view are hidden in | 372 // Ensure that any browser actions shown in the main view are hidden in |
381 // the overflow view. | 373 // the overflow view. |
382 browser_action_views_[i]->SetVisible(false); | 374 browser_action_views_[i]->SetVisible(false); |
383 } | 375 } |
384 | 376 |
385 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); | 377 for (size_t i = main_container_->VisibleBrowserActionsAfterAnimation(); |
386 i < browser_action_views_.size(); ++i) { | 378 i < browser_action_views_.size(); ++i) { |
387 BrowserActionView* view = browser_action_views_[i]; | 379 BrowserActionView* view = browser_action_views_[i]; |
388 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); | 380 size_t index = i - main_container_->VisibleBrowserActionsAfterAnimation(); |
389 int row_index = static_cast<int>(index) / kIconsPerMenuRow; | 381 int row_index = static_cast<int>(index) / icons_per_menu_row; |
390 int x = kItemSpacing + (index * IconWidth(true)) - | 382 int x = kItemSpacing + (index * IconWidth(true)) - |
391 (row_index * IconWidth(true) * kIconsPerMenuRow); | 383 (row_index * IconWidth(true) * icons_per_menu_row); |
392 gfx::Rect rect_bounds( | 384 gfx::Rect rect_bounds( |
393 x, IconHeight() * row_index, icon_width, IconHeight()); | 385 x, IconHeight() * row_index, icon_width, IconHeight()); |
394 view->SetBoundsRect(rect_bounds); | 386 view->SetBoundsRect(rect_bounds); |
395 view->SetVisible(true); | 387 view->SetVisible(true); |
396 } | 388 } |
397 } else { | 389 } else { |
398 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); | 390 for (BrowserActionViews::const_iterator it = browser_action_views_.begin(); |
399 it < browser_action_views_.end(); ++it) { | 391 it < browser_action_views_.end(); ++it) { |
400 BrowserActionView* view = *it; | 392 BrowserActionView* view = *it; |
401 int x = ToolbarView::kStandardSpacing + | 393 int x = ToolbarView::kStandardSpacing + |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 kItemSpacing) / IconWidth(true); | 468 kItemSpacing) / IconWidth(true); |
477 | 469 |
478 // We need to figure out how many icons are visible on the relevant row. | 470 // We need to figure out how many icons are visible on the relevant row. |
479 // In the main container, this will just be the visible actions. | 471 // In the main container, this will just be the visible actions. |
480 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); | 472 int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
481 if (in_overflow_mode()) { | 473 if (in_overflow_mode()) { |
482 // If this is the final row of the overflow, then this is the remainder of | 474 // If this is the final row of the overflow, then this is the remainder of |
483 // visible icons. Otherwise, it's a full row (kIconsPerRow). | 475 // visible icons. Otherwise, it's a full row (kIconsPerRow). |
484 visible_icons_on_row = | 476 visible_icons_on_row = |
485 row_index == | 477 row_index == |
486 static_cast<size_t>(visible_icons_on_row / kIconsPerMenuRow) ? | 478 static_cast<size_t>(visible_icons_on_row / icons_per_menu_row) ? |
487 visible_icons_on_row % kIconsPerMenuRow : | 479 visible_icons_on_row % icons_per_menu_row : |
488 kIconsPerMenuRow; | 480 icons_per_menu_row; |
489 } | 481 } |
490 | 482 |
491 // Because the user can drag outside the container bounds, we need to clamp to | 483 // Because the user can drag outside the container bounds, we need to clamp to |
492 // the valid range. Note that the maximum allowable value is (num icons), not | 484 // the valid range. Note that the maximum allowable value is (num icons), not |
493 // (num icons - 1), because we represent the indicator being past the last | 485 // (num icons - 1), because we represent the indicator being past the last |
494 // icon as being "before the (last + 1) icon". | 486 // icon as being "before the (last + 1) icon". |
495 size_t before_icon_in_row = | 487 size_t before_icon_in_row = |
496 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); | 488 std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); |
497 | 489 |
498 if (!drop_position_.get() || | 490 if (!drop_position_.get() || |
(...skipping 17 matching lines...) Expand all Loading... | |
516 BrowserActionDragData data; | 508 BrowserActionDragData data; |
517 if (!data.Read(event.data())) | 509 if (!data.Read(event.data())) |
518 return ui::DragDropTypes::DRAG_NONE; | 510 return ui::DragDropTypes::DRAG_NONE; |
519 | 511 |
520 // Make sure we have the same view as we started with. | 512 // Make sure we have the same view as we started with. |
521 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), | 513 DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(), |
522 data.id()); | 514 data.id()); |
523 DCHECK(model_); | 515 DCHECK(model_); |
524 | 516 |
525 size_t i = | 517 size_t i = |
526 drop_position_->row * kIconsPerMenuRow + drop_position_->icon_in_row; | 518 drop_position_->row * icons_per_menu_row + drop_position_->icon_in_row; |
Finnur
2014/09/10 10:48:27
Danger! Danger! Drop can be broken if the wrench m
Devlin
2014/09/10 16:14:26
Can it, though?
In the main container, there are
Finnur
2014/09/11 09:12:43
Good.
| |
527 if (in_overflow_mode()) | 519 if (in_overflow_mode()) |
528 i += GetFirstVisibleIconIndex(); | 520 i += GetFirstVisibleIconIndex(); |
529 // |i| now points to the item to the right of the drop indicator*, which is | 521 // |i| now points to the item to the right of the drop indicator*, which is |
530 // correct when dragging an icon to the left. When dragging to the right, | 522 // correct when dragging an icon to the left. When dragging to the right, |
531 // however, we want the icon being dragged to get the index of the item to | 523 // however, we want the icon being dragged to get the index of the item to |
532 // the left of the drop indicator, so we subtract one. | 524 // the left of the drop indicator, so we subtract one. |
533 // * Well, it can also point to the end, but not when dragging to the left. :) | 525 // * Well, it can also point to the end, but not when dragging to the left. :) |
534 if (i > data.index()) | 526 if (i > data.index()) |
535 --i; | 527 --i; |
536 | 528 |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1001 int BrowserActionsContainer::IconCountToWidth(int icons, | 993 int BrowserActionsContainer::IconCountToWidth(int icons, |
1002 bool display_chevron) const { | 994 bool display_chevron) const { |
1003 if (icons < 0) | 995 if (icons < 0) |
1004 icons = browser_action_views_.size(); | 996 icons = browser_action_views_.size(); |
1005 if ((icons == 0) && !display_chevron) | 997 if ((icons == 0) && !display_chevron) |
1006 return ToolbarView::kStandardSpacing; | 998 return ToolbarView::kStandardSpacing; |
1007 int icons_size = | 999 int icons_size = |
1008 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); | 1000 (icons == 0) ? 0 : ((icons * IconWidth(true)) - kItemSpacing); |
1009 int chevron_size = chevron_ && display_chevron ? | 1001 int chevron_size = chevron_ && display_chevron ? |
1010 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; | 1002 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; |
1011 return ToolbarView::kStandardSpacing + icons_size + chevron_size + | 1003 // In overflow mode, our padding is to use item spacing on either end (just so |
1012 ToolbarView::kStandardSpacing; | 1004 // we can see the drop indicator). Otherwise we use the standard toolbar |
1005 // spacing. | |
1006 // Note: These are actually the same thing, but, on the offchance one | |
1007 // changes, let's get it right. | |
1008 int padding = | |
1009 2 * (in_overflow_mode() ? kItemSpacing : ToolbarView::kStandardSpacing); | |
1010 return icons_size + chevron_size + padding; | |
1013 } | 1011 } |
1014 | 1012 |
1015 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { | 1013 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { |
1016 // Check for widths large enough to show the entire icon set. | 1014 // Check for widths large enough to show the entire icon set. |
1017 if (pixels >= IconCountToWidth(-1, false)) | 1015 if (pixels >= IconCountToWidth(-1, false)) |
1018 return browser_action_views_.size(); | 1016 return browser_action_views_.size(); |
1019 | 1017 |
1020 // We need to reserve space for the resize area, chevron, and the spacing on | 1018 // We need to reserve space for the resize area, chevron, and the spacing on |
1021 // either side of the chevron. | 1019 // either side of the chevron. |
1022 int available_space = pixels - ToolbarView::kStandardSpacing - | 1020 int available_space = pixels - ToolbarView::kStandardSpacing - |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1074 size_t absolute_model_size = | 1072 size_t absolute_model_size = |
1075 model_size == -1 ? extensions.size() : model_size; | 1073 model_size == -1 ? extensions.size() : model_size; |
1076 | 1074 |
1077 // The main container will try to show |model_size| icons, but reduce if there | 1075 // The main container will try to show |model_size| icons, but reduce if there |
1078 // aren't enough displayable icons to do so. | 1076 // aren't enough displayable icons to do so. |
1079 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); | 1077 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); |
1080 // The overflow will display the extras, if any. | 1078 // The overflow will display the extras, if any. |
1081 return in_overflow_mode() ? | 1079 return in_overflow_mode() ? |
1082 displayable_icon_count - main_displayed : main_displayed; | 1080 displayable_icon_count - main_displayed : main_displayed; |
1083 } | 1081 } |
OLD | NEW |