| Index: ash/launcher/launcher_view.cc
|
| diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc
|
| index 94c4a822512eeea9585cec1c4a1c5b87e4794bf4..9991bdb9b22c306e34575492abf492afa4105957 100644
|
| --- a/ash/launcher/launcher_view.cc
|
| +++ b/ash/launcher/launcher_view.cc
|
| @@ -12,6 +12,7 @@
|
| #include "ash/launcher/launcher_icon_observer.h"
|
| #include "ash/launcher/launcher_model.h"
|
| #include "ash/launcher/launcher_tooltip_manager.h"
|
| +#include "ash/launcher/overflow_bubble.h"
|
| #include "ash/launcher/tabbed_launcher_button.h"
|
| #include "ash/shell.h"
|
| #include "ash/shell_delegate.h"
|
| @@ -44,8 +45,8 @@ using views::View;
|
| namespace ash {
|
| namespace internal {
|
|
|
| -// Amount content is inset on the left edge.
|
| -static const int kLeadingInset = 8;
|
| +// Default amount content is inset on the left edge.
|
| +static const int kDefaultLeadingInset = 8;
|
|
|
| // Minimum distance before drag starts.
|
| static const int kMinimumDragDistance = 8;
|
| @@ -267,6 +268,7 @@ LauncherView::LauncherView(LauncherModel* model,
|
| : model_(model),
|
| delegate_(delegate),
|
| view_model_(new views::ViewModel),
|
| + first_visible_index_(0),
|
| last_visible_index_(-1),
|
| overflow_button_(NULL),
|
| dragging_(false),
|
| @@ -274,7 +276,8 @@ LauncherView::LauncherView(LauncherModel* model,
|
| drag_offset_(0),
|
| start_drag_index_(-1),
|
| context_menu_id_(0),
|
| - alignment_(SHELF_ALIGNMENT_BOTTOM) {
|
| + alignment_(SHELF_ALIGNMENT_BOTTOM),
|
| + leading_inset_(kDefaultLeadingInset) {
|
| DCHECK(model_);
|
| bounds_animator_.reset(new views::BoundsAnimator(this));
|
| bounds_animator_->AddObserver(this);
|
| @@ -303,6 +306,8 @@ void LauncherView::Init() {
|
|
|
| overflow_button_ = new views::ImageButton(this);
|
| overflow_button_->set_accessibility_focusable(true);
|
| + overflow_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
|
| + views::ImageButton::ALIGN_MIDDLE);
|
| overflow_button_->SetImage(
|
| views::CustomButton::BS_NORMAL,
|
| rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToImageSkia());
|
| @@ -328,6 +333,8 @@ void LauncherView::SetAlignment(ShelfAlignment alignment) {
|
| UpdateFirstButtonPadding();
|
| LayoutToIdealBounds();
|
| tooltip_->SetArrowLocation(alignment_);
|
| + if (overflow_bubble_.get())
|
| + overflow_bubble_->Hide();
|
| }
|
|
|
| gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) {
|
| @@ -346,14 +353,16 @@ gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) {
|
|
|
| bool LauncherView::IsShowingMenu() const {
|
| #if !defined(OS_MACOSX)
|
| - return (overflow_menu_runner_.get() &&
|
| - overflow_menu_runner_->IsRunning()) ||
|
| - (launcher_menu_runner_.get() &&
|
| + return (launcher_menu_runner_.get() &&
|
| launcher_menu_runner_->IsRunning());
|
| #endif
|
| return false;
|
| }
|
|
|
| +bool LauncherView::IsShowingOverflowBubble() const {
|
| + return overflow_bubble_.get() && overflow_bubble_->IsShowing();
|
| +}
|
| +
|
| views::View* LauncherView::GetAppListButtonView() const {
|
| for (int i = 0; i < model_->item_count(); ++i) {
|
| if (model_->items()[i].type == TYPE_APP_LIST)
|
| @@ -396,30 +405,44 @@ void LauncherView::CalculateIdealBounds(IdealBounds* bounds) {
|
| if (!available_size)
|
| return;
|
|
|
| - int x = primary_axis_coordinate(kLeadingInset, 0);
|
| - int y = primary_axis_coordinate(0, kLeadingInset);
|
| + int x = primary_axis_coordinate(leading_inset(), 0);
|
| + int y = primary_axis_coordinate(0, leading_inset());
|
| for (int i = 0; i < view_model_->view_size(); ++i) {
|
| + if (i < first_visible_index_) {
|
| + view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0));
|
| + continue;
|
| + }
|
| +
|
| view_model_->set_ideal_bounds(i, gfx::Rect(
|
| x, y, kLauncherPreferredSize, kLauncherPreferredSize));
|
| x = primary_axis_coordinate(x + kLauncherPreferredSize + kButtonSpacing, 0);
|
| y = primary_axis_coordinate(0, y + kLauncherPreferredSize + kButtonSpacing);
|
| }
|
|
|
| + int app_list_index = view_model_->view_size() - 1;
|
| + if (is_overflow_mode()) {
|
| + last_visible_index_ = app_list_index - 1;
|
| + for (int i = 0; i < view_model_->view_size(); ++i) {
|
| + view_model_->view_at(i)->SetVisible(
|
| + i >= first_visible_index_ && i <= last_visible_index_);
|
| + }
|
| + return;
|
| + }
|
| +
|
| if (view_model_->view_size() > 0) {
|
| // Makes the first launcher button include the leading inset.
|
| view_model_->set_ideal_bounds(0, gfx::Rect(gfx::Size(
|
| - primary_axis_coordinate(kLeadingInset + kLauncherPreferredSize,
|
| + primary_axis_coordinate(leading_inset() + kLauncherPreferredSize,
|
| kLauncherPreferredSize),
|
| primary_axis_coordinate(kLauncherPreferredSize,
|
| - kLeadingInset + kLauncherPreferredSize))));
|
| + leading_inset() + kLauncherPreferredSize))));
|
| }
|
|
|
| bounds->overflow_bounds.set_size(
|
| gfx::Size(kLauncherPreferredSize, kLauncherPreferredSize));
|
| last_visible_index_ = DetermineLastVisibleIndex(
|
| - available_size - kLeadingInset - kLauncherPreferredSize -
|
| + available_size - leading_inset() - kLauncherPreferredSize -
|
| kButtonSpacing - kLauncherPreferredSize);
|
| - int app_list_index = view_model_->view_size() - 1;
|
| bool show_overflow = (last_visible_index_ + 1 < app_list_index);
|
|
|
| for (int i = 0; i < view_model_->view_size(); ++i) {
|
| @@ -431,8 +454,8 @@ void LauncherView::CalculateIdealBounds(IdealBounds* bounds) {
|
| if (show_overflow) {
|
| DCHECK_NE(0, view_model_->view_size());
|
| if (last_visible_index_ == -1) {
|
| - x = primary_axis_coordinate(kLeadingInset, 0);
|
| - y = primary_axis_coordinate(0, kLeadingInset);
|
| + x = primary_axis_coordinate(leading_inset(), 0);
|
| + y = primary_axis_coordinate(0, leading_inset());
|
| } else {
|
| x = primary_axis_coordinate(
|
| view_model_->ideal_bounds(last_visible_index_).right(), 0);
|
| @@ -440,13 +463,16 @@ void LauncherView::CalculateIdealBounds(IdealBounds* bounds) {
|
| view_model_->ideal_bounds(last_visible_index_).bottom());
|
| }
|
| gfx::Rect app_list_bounds = view_model_->ideal_bounds(app_list_index);
|
| + bounds->overflow_bounds.set_x(x);
|
| + bounds->overflow_bounds.set_y(y);
|
| + x = primary_axis_coordinate(x + kLauncherPreferredSize + kButtonSpacing, 0);
|
| + y = primary_axis_coordinate(0, y + kLauncherPreferredSize + kButtonSpacing);
|
| app_list_bounds.set_x(x);
|
| app_list_bounds.set_y(y);
|
| view_model_->set_ideal_bounds(app_list_index, app_list_bounds);
|
| - x = primary_axis_coordinate(x + kLauncherPreferredSize + kButtonSpacing, 0);
|
| - y = primary_axis_coordinate(0, y + kLauncherPreferredSize + kButtonSpacing);
|
| - bounds->overflow_bounds.set_x(x);
|
| - bounds->overflow_bounds.set_y(y);
|
| + } else {
|
| + if (overflow_bubble_.get())
|
| + overflow_bubble_->Hide();
|
| }
|
| }
|
|
|
| @@ -686,41 +712,20 @@ void LauncherView::GetOverflowItems(std::vector<LauncherItem>* items) {
|
| }
|
| }
|
|
|
| -void LauncherView::ShowOverflowMenu() {
|
| -#if !defined(OS_MACOSX)
|
| - if (!delegate_)
|
| - return;
|
| +void LauncherView::ShowOverflowBubble() {
|
| + int first_overflow_index = last_visible_index_ + 1;
|
| + DCHECK_LT(first_overflow_index, view_model_->view_size() - 1);
|
|
|
| - std::vector<LauncherItem> items;
|
| - GetOverflowItems(&items);
|
| - if (items.empty())
|
| - return;
|
| + if (!overflow_bubble_.get())
|
| + overflow_bubble_.reset(new OverflowBubble());
|
|
|
| - MenuDelegateImpl menu_delegate;
|
| - ui::SimpleMenuModel menu_model(&menu_delegate);
|
| - for (size_t i = 0; i < items.size(); ++i)
|
| - menu_model.AddItem(static_cast<int>(i), delegate_->GetTitle(items[i]));
|
| - views::MenuModelAdapter menu_adapter(&menu_model);
|
| - overflow_menu_runner_.reset(new views::MenuRunner(menu_adapter.CreateMenu()));
|
| - gfx::Rect bounds(overflow_button_->size());
|
| - gfx::Point origin;
|
| - ConvertPointToScreen(overflow_button_, &origin);
|
| - if (overflow_menu_runner_->RunMenuAt(GetWidget(), NULL,
|
| - gfx::Rect(origin, size()), views::MenuItemView::TOPLEFT, 0) ==
|
| - views::MenuRunner::MENU_DELETED)
|
| - return;
|
| + overflow_bubble_->Show(delegate_,
|
| + model_,
|
| + overflow_button_,
|
| + alignment_,
|
| + first_overflow_index);
|
|
|
| Shell::GetInstance()->UpdateShelfVisibility();
|
| -
|
| - if (menu_delegate.activated_command_id() == -1)
|
| - return;
|
| -
|
| - LauncherID activated_id = items[menu_delegate.activated_command_id()].id;
|
| - LauncherItems::const_iterator window_iter = model_->ItemByID(activated_id);
|
| - if (window_iter == model_->items().end())
|
| - return; // Window was deleted while menu was up.
|
| - delegate_->ItemClicked(*window_iter, ui::EF_NONE);
|
| -#endif // !defined(OS_MACOSX)
|
| }
|
|
|
| void LauncherView::UpdateFirstButtonPadding() {
|
| @@ -729,8 +734,8 @@ void LauncherView::UpdateFirstButtonPadding() {
|
| // and when shelf alignment changes.
|
| if (view_model_->view_size() > 0) {
|
| view_model_->view_at(0)->set_border(views::Border::CreateEmptyBorder(
|
| - primary_axis_coordinate(0, kLeadingInset),
|
| - primary_axis_coordinate(kLeadingInset, 0),
|
| + primary_axis_coordinate(0, leading_inset()),
|
| + primary_axis_coordinate(leading_inset(), 0),
|
| 0,
|
| 0));
|
| }
|
| @@ -775,28 +780,32 @@ int LauncherView::CancelDrag(int modified_index) {
|
| gfx::Size LauncherView::GetPreferredSize() {
|
| IdealBounds ideal_bounds;
|
| CalculateIdealBounds(&ideal_bounds);
|
| +
|
| + const int app_list_index = view_model_->view_size() - 1;
|
| + const int last_button_index = is_overflow_mode() ?
|
| + last_visible_index_ : app_list_index;
|
| + const gfx::Rect last_button_bounds =
|
| + last_button_index >= first_visible_index_ ?
|
| + view_model_->view_at(last_button_index)->bounds() :
|
| + gfx::Rect(gfx::Size(kLauncherPreferredSize,
|
| + kLauncherPreferredSize));
|
| +
|
| if (is_horizontal_alignment()) {
|
| - if (view_model_->view_size() >= 2) {
|
| - // Should always have two items.
|
| - return gfx::Size(view_model_->ideal_bounds(1).right() + kLeadingInset,
|
| - kLauncherPreferredSize);
|
| - }
|
| - return gfx::Size(kLauncherPreferredSize * 2 + kLeadingInset * 2,
|
| + return gfx::Size(last_button_bounds.right() + leading_inset(),
|
| kLauncherPreferredSize);
|
| }
|
| - if (view_model_->view_size() >= 2) {
|
| - // Should always have two items.
|
| - return gfx::Size(kLauncherPreferredSize,
|
| - view_model_->ideal_bounds(1).bottom() + kLeadingInset);
|
| - }
|
| +
|
| return gfx::Size(kLauncherPreferredSize,
|
| - kLauncherPreferredSize * 2 + kLeadingInset * 2);
|
| + last_button_bounds.bottom() + leading_inset());
|
| }
|
|
|
| void LauncherView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
|
| LayoutToIdealBounds();
|
| FOR_EACH_OBSERVER(LauncherIconObserver, observers_,
|
| OnLauncherIconPositionsChanged());
|
| +
|
| + if (IsShowingOverflowBubble())
|
| + overflow_bubble_->Hide();
|
| }
|
|
|
| views::FocusTraversable* LauncherView::GetPaneFocusTraversable() {
|
| @@ -1002,8 +1011,10 @@ void LauncherView::ButtonPressed(views::Button* sender,
|
| if (dragging_)
|
| return;
|
|
|
| - if (sender == overflow_button_)
|
| - ShowOverflowMenu();
|
| + if (sender == overflow_button_) {
|
| + ShowOverflowBubble();
|
| + return;
|
| + }
|
|
|
| if (!delegate_)
|
| return;
|
| @@ -1070,6 +1081,7 @@ void LauncherView::ShowContextMenuForView(views::View* source,
|
| void LauncherView::OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) {
|
| FOR_EACH_OBSERVER(LauncherIconObserver, observers_,
|
| OnLauncherIconPositionsChanged());
|
| + PreferredSizeChanged();
|
| }
|
|
|
| void LauncherView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) {
|
|
|