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

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

Issue 553233002: Dynamically calculate the number of extension icons to show per row in overflow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698