Chromium Code Reviews| Index: chrome/browser/ui/views/toolbar/browser_actions_container.cc |
| diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
| index 9bababa6e6a9b3d36196f60a410d1e9d94933190..a792a856e3866cfd39e41b1a68bea6e4a2cedfb1 100644 |
| --- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
| +++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
| @@ -268,8 +268,12 @@ void BrowserActionsContainer::ExecuteExtensionCommand( |
| void BrowserActionsContainer::NotifyActionMovedToOverflow() { |
| // When an action is moved to overflow, we shrink the size of the container |
| // by 1. |
| - if (!profile_->IsOffTheRecord()) |
| - model_->SetVisibleIconCount(model_->GetVisibleIconCount() - 1); |
| + if (!profile_->IsOffTheRecord()) { |
| + int icon_count = model_->GetVisibleIconCount(); |
| + if (icon_count == -1) |
| + icon_count = browser_action_views_.size(); |
| + model_->SetVisibleIconCount(icon_count - 1); |
|
Peter Kasting
2014/09/16 21:40:54
What if |icon_count| is 0? Do we really want to c
Devlin
2014/09/16 21:58:29
Interestingly, VisibleIconCount() *cannot* be 0 he
|
| + } |
| Animate(gfx::Tween::EASE_OUT, |
| VisibleBrowserActionsAfterAnimation() - 1); |
| } |
| @@ -322,23 +326,22 @@ void BrowserActionsContainer::RemoveObserver( |
| } |
| gfx::Size BrowserActionsContainer::GetPreferredSize() const { |
| - // Note: We can't use GetIconCount() for the main bar, since we may also |
| - // have to include items that are in the chevron's overflow. |
| - size_t icon_count = |
| - in_overflow_mode() ? GetIconCount() : browser_action_views_.size(); |
| - |
| - // If there are no actions to show, or we are in overflow mode and the main |
| - // container is already showing them all, then no further work is required. |
| - if (icon_count == 0) |
| - return gfx::Size(); |
| - |
| if (in_overflow_mode()) { |
| - // When in overflow, y is multiline, so the pixel count is IconHeight() |
| - // times the number of rows needed. |
| + int icon_count = GetIconCount(); |
| + // In overflow, we always have a preferred size of a full row (even if we |
| + // don't use it), and always of at least one row. If there's nothing to |
| + // display, the container won't be shown. |
|
Peter Kasting
2014/09/16 21:40:54
Nit: Isn't this comment incorrect, in that sometim
Devlin
2014/09/16 21:58:29
Fair - I was counting a "drop area" as "something
|
| + int row_count = |
| + ((std::max(0, icon_count - 1)) / icons_per_overflow_menu_row_) + 1; |
| return gfx::Size( |
| IconCountToWidth(icons_per_overflow_menu_row_, false), |
| - (((icon_count - 1) / icons_per_overflow_menu_row_) + 1) * IconHeight()); |
| + row_count * IconHeight()); |
| } |
| + DCHECK(!in_overflow_mode()); |
|
Peter Kasting
2014/09/16 21:40:54
Nit: I'd remove this DCHECK as it's obviously true
Devlin
2014/09/16 21:58:29
Done.
|
| + |
| + // If there are no actions to show, then don't show the container at all. |
| + if (browser_action_views_.size() == 0) |
|
Peter Kasting
2014/09/16 21:40:54
Nit: empty()?
Devlin
2014/09/16 21:58:29
Done.
|
| + return gfx::Size(); |
| // We calculate the size of the view by taking the current width and |
| // subtracting resize_amount_ (the latter represents how far the user is |
| @@ -448,70 +451,73 @@ int BrowserActionsContainer::OnDragUpdated( |
| } |
| StopShowFolderDropMenuTimer(); |
| - // Figure out where to display the indicator. This is a complex calculation: |
| - |
| - // First, we figure out how much space is to the left of the icon area, so we |
| - // can calculate the true offset into the icon area. The easiest way to do |
| - // this is to just find where the first icon starts. |
| - int width_before_icons = |
| - browser_action_views_[GetFirstVisibleIconIndex()]->x(); |
| - |
| - // If we're right-to-left, we flip the mirror the event.x() so that our |
| - // calculations are consistent with left-to-right. |
| - int offset_into_icon_area = |
| - GetMirroredXInView(event.x()) - width_before_icons; |
| - |
| - // Next, figure out what row we're on. This only matters for overflow mode, |
| - // but the calculation is the same for both. |
| - size_t row_index = event.y() / IconHeight(); |
| - |
| - // Sanity check - we should never be on a different row in the main container. |
| - DCHECK(in_overflow_mode() || row_index == 0); |
| - |
| - // Next, we determine which icon to place the indicator in front of. We want |
| - // to place the indicator in front of icon n when the cursor is between the |
| - // midpoints of icons (n - 1) and n. To do this we take the offset into the |
| - // icon area and transform it as follows: |
| - // |
| - // Real icon area: |
| - // 0 a * b c |
| - // | | | | |
| - // |[IC|ON] [IC|ON] [IC|ON] |
| - // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc. |
| - // Here the "*" represents the offset into the icon area, and since it's |
| - // between a and b, we want to return "1". |
| - // |
| - // Transformed "icon area": |
| - // 0 a * b c |
| - // | | | | |
| - // |[ICON] |[ICON] |[ICON] | |
| - // If we shift both our offset and our divider points later by half an icon |
| - // plus one spacing unit, then it becomes very easy to calculate how many |
| - // divider points we've passed, because they're the multiples of "one icon |
| - // plus padding". |
| - int before_icon_unclamped = (offset_into_icon_area + (IconWidth(false) / 2) + |
| - kItemSpacing) / IconWidth(true); |
| - |
| - // We need to figure out how many icons are visible on the relevant row. |
| - // In the main container, this will just be the visible actions. |
| - int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
| - if (in_overflow_mode()) { |
| - // If this is the final row of the overflow, then this is the remainder of |
| - // visible icons. Otherwise, it's a full row (kIconsPerRow). |
| - visible_icons_on_row = |
| - row_index == |
| - static_cast<size_t>(visible_icons_on_row / |
| - icons_per_overflow_menu_row_) ? |
| - visible_icons_on_row % icons_per_overflow_menu_row_ : |
| - icons_per_overflow_menu_row_; |
| - } |
| + size_t row_index = 0; |
| + size_t before_icon_in_row = 0; |
| + // If there are no visible browser actions (such as when dragging an icon to |
| + // an empty overflow/main container), then 0, 0 for row, column is correct. |
| + if (VisibleBrowserActions() != 0) { |
| + // Figure out where to display the indicator. This is a complex calculation: |
|
Devlin
2014/09/16 19:28:35
The body of this if is just the indented version o
|
| + |
| + // First, we subtract out the padding to the left of the icon area, which is |
| + // ToolbarView::kStandardSpacing. If we're right-to-left, we also mirror the |
| + // event.x() so that our calculations are consistent with left-to-right. |
| + int offset_into_icon_area = |
| + GetMirroredXInView(event.x()) - ToolbarView::kStandardSpacing; |
| + |
| + // Next, figure out what row we're on. This only matters for overflow mode, |
| + // but the calculation is the same for both. |
| + row_index = event.y() / IconHeight(); |
| + |
| + // Sanity check - we should never be on a different row in the main |
| + // container. |
| + DCHECK(in_overflow_mode() || row_index == 0); |
| + |
| + // Next, we determine which icon to place the indicator in front of. We want |
| + // to place the indicator in front of icon n when the cursor is between the |
| + // midpoints of icons (n - 1) and n. To do this we take the offset into the |
| + // icon area and transform it as follows: |
| + // |
| + // Real icon area: |
| + // 0 a * b c |
| + // | | | | |
| + // |[IC|ON] [IC|ON] [IC|ON] |
| + // We want to be before icon 0 for 0 < x <= a, icon 1 for a < x <= b, etc. |
| + // Here the "*" represents the offset into the icon area, and since it's |
| + // between a and b, we want to return "1". |
| + // |
| + // Transformed "icon area": |
| + // 0 a * b c |
| + // | | | | |
| + // |[ICON] |[ICON] |[ICON] | |
| + // If we shift both our offset and our divider points later by half an icon |
| + // plus one spacing unit, then it becomes very easy to calculate how many |
| + // divider points we've passed, because they're the multiples of "one icon |
| + // plus padding". |
| + int before_icon_unclamped = |
| + (offset_into_icon_area + (IconWidth(false) / 2) + |
| + kItemSpacing) / IconWidth(true); |
| + |
| + // We need to figure out how many icons are visible on the relevant row. |
| + // In the main container, this will just be the visible actions. |
| + int visible_icons_on_row = VisibleBrowserActionsAfterAnimation(); |
| + if (in_overflow_mode()) { |
| + // If this is the final row of the overflow, then this is the remainder of |
| + // visible icons. Otherwise, it's a full row (kIconsPerRow). |
| + visible_icons_on_row = |
| + row_index == |
| + static_cast<size_t>(visible_icons_on_row / |
| + icons_per_overflow_menu_row_) ? |
| + visible_icons_on_row % icons_per_overflow_menu_row_ : |
| + icons_per_overflow_menu_row_; |
| + } |
| - // Because the user can drag outside the container bounds, we need to clamp to |
| - // the valid range. Note that the maximum allowable value is (num icons), not |
| - // (num icons - 1), because we represent the indicator being past the last |
| - // icon as being "before the (last + 1) icon". |
| - size_t before_icon_in_row = |
| - std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); |
| + // Because the user can drag outside the container bounds, we need to clamp |
| + // to the valid range. Note that the maximum allowable value is (num icons), |
| + // not (num icons - 1), because we represent the indicator being past the |
| + // last icon as being "before the (last + 1) icon". |
| + before_icon_in_row = |
| + std::min(std::max(before_icon_unclamped, 0), visible_icons_on_row); |
| + } |
| if (!drop_position_.get() || |
| !(drop_position_->row == row_index && |
| @@ -543,7 +549,7 @@ int BrowserActionsContainer::OnPerformDrop( |
| size_t i = drop_position_->row * icons_per_overflow_menu_row_ + |
| drop_position_->icon_in_row; |
| if (in_overflow_mode()) |
| - i += GetFirstVisibleIconIndex(); |
| + i += main_container_->VisibleBrowserActionsAfterAnimation(); |
|
Peter Kasting
2014/09/16 21:40:54
It looks like now |i| is going to be based on the
Devlin
2014/09/16 21:58:29
Line 551 ensures that we're in the overflow contai
Peter Kasting
2014/09/16 22:08:49
I know. I'm saying, the old code here called GetF
Devlin
2014/09/16 22:10:39
GetFirstVisibleIconIndex() would always return mai
Peter Kasting
2014/09/16 22:15:57
Oh, I'm dumb, I mentally reversed the contents of
Devlin
2014/09/16 22:25:37
Happens to all of us. :)
|
| // |i| now points to the item to the right of the drop indicator*, which is |
| // correct when dragging an icon to the left. When dragging to the right, |
| // however, we want the icon being dragged to get the index of the item to |
| @@ -702,11 +708,6 @@ extensions::ActiveTabPermissionGranter* |
| active_tab_permission_granter(); |
| } |
| -size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const { |
| - return in_overflow_mode() ? |
| - main_container_->VisibleBrowserActionsAfterAnimation() : 0; |
| -} |
| - |
| ExtensionPopup* BrowserActionsContainer::TestGetPopup() { |
| return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL; |
| } |
| @@ -731,8 +732,8 @@ void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { |
| // Convert back to a pixel offset into the container. First find the X |
| // coordinate of the drop icon. |
| - int drop_icon_x = browser_action_views_[GetFirstVisibleIconIndex()]->x() + |
| - (drop_position_->icon_in_row * IconWidth(true)); |
| + int drop_icon_x = ToolbarView::kStandardSpacing + |
|
Peter Kasting
2014/09/16 21:40:54
This seems very different than the old code. Why
Devlin
2014/09/16 21:58:29
Before, we would say "The start of the first visib
|
| + (drop_position_->icon_in_row * IconWidth(true)); |
|
Peter Kasting
2014/09/16 21:40:54
Nit: Previous indenting was correct
Devlin
2014/09/16 21:58:29
changed back.
|
| // Next, find the space before the drop icon. This will either be |
| // kItemSpacing or ToolbarView::kStandardSpacing, depending on whether this |
| // is the first icon. |