Chromium Code Reviews| Index: ash/app_list/app_list_view.cc |
| diff --git a/ash/app_list/app_list_view.cc b/ash/app_list/app_list_view.cc |
| index 4e47e3654cbf49e140e34b2ac6ae931f57183145..fafb7795bf20035d46ee3f970ef8983386c02934 100644 |
| --- a/ash/app_list/app_list_view.cc |
| +++ b/ash/app_list/app_list_view.cc |
| @@ -4,10 +4,15 @@ |
| #include "ash/app_list/app_list_view.h" |
| +#include "ash/app_list/app_list.h" |
| +#include "ash/app_list/app_list_bubble_border.h" |
| #include "ash/app_list/app_list_item_view.h" |
| #include "ash/app_list/app_list_model.h" |
| #include "ash/app_list/app_list_model_view.h" |
| #include "ash/app_list/app_list_view_delegate.h" |
| +#include "ash/app_list/page_switcher.h" |
| +#include "ash/app_list/pagination_model.h" |
| +#include "ash/launcher/launcher.h" |
| #include "ash/screen_ash.h" |
| #include "ash/shell.h" |
| #include "ash/shell_window_ids.h" |
| @@ -17,6 +22,8 @@ |
| #include "ui/gfx/screen.h" |
| #include "ui/gfx/transform_util.h" |
| #include "ui/views/background.h" |
| +#include "ui/views/bubble/bubble_frame_view.h" |
| +#include "ui/views/layout/box_layout.h" |
| #include "ui/views/widget/widget.h" |
| namespace ash { |
| @@ -24,25 +31,43 @@ namespace ash { |
| namespace { |
| // 0.2 black |
| -const SkColor kBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); |
| +const SkColor kWidgetBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); |
| const float kModelViewAnimationScaleFactor = 0.9f; |
| +const int kPreferredIconDimension = 48; |
| +const int kPreferredCols = 4; |
| +const int kPreferredRows = 4; |
| +const int kModelViewFooterPadding = 10; |
|
sky
2012/05/06 22:51:15
nit: this last one isn't that obvious, add a descr
xiyuan
2012/05/07 16:46:10
Done.
|
| + |
| ui::Transform GetScaleTransform(AppListModelView* model_view) { |
| gfx::Rect pixel_bounds = model_view->GetLayerBoundsInPixel(); |
| gfx::Point center(pixel_bounds.width() / 2, pixel_bounds.height() / 2); |
| return ui::GetScaleTransform(center, kModelViewAnimationScaleFactor); |
| } |
| +// Bounds returned is used for full screen mode. Use full monitor rect so that |
| +// the app list shade goes behind the launcher. |
| +gfx::Rect GetFullScreenBounds() { |
| + gfx::Point cursor = gfx::Screen::GetCursorScreenPoint(); |
| + return gfx::Screen::GetMonitorNearestPoint(cursor).bounds(); |
| +} |
| + |
| } // namespace |
| -AppListView::AppListView( |
| - AppListViewDelegate* delegate, |
| - const gfx::Rect& bounds) |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// AppListView: |
| + |
| +AppListView::AppListView(AppListViewDelegate* delegate) |
| : delegate_(delegate), |
| + pagination_model_(new PaginationModel), |
| + bubble_style_(false), |
| + bubble_border_(NULL), |
| model_view_(NULL) { |
| - set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
| - Init(bounds); |
| + if (internal::AppList::UseAppListV2()) |
| + InitAsBubble(); |
| + else |
| + InitAsFullscreenWidget(); |
| } |
| AppListView::~AppListView() { |
| @@ -52,6 +77,9 @@ AppListView::~AppListView() { |
| } |
| void AppListView::AnimateShow(int duration_ms) { |
| + if (bubble_style_) |
| + return; |
| + |
| ui::Layer* layer = model_view_->layer(); |
| ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| animation.SetTransitionDuration( |
| @@ -61,6 +89,9 @@ void AppListView::AnimateShow(int duration_ms) { |
| } |
| void AppListView::AnimateHide(int duration_ms) { |
| + if (bubble_style_) |
| + return; |
| + |
| ui::Layer* layer = model_view_->layer(); |
| ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| animation.SetTransitionDuration( |
| @@ -74,8 +105,19 @@ void AppListView::Close() { |
| Shell::GetInstance()->ToggleAppList(); |
| } |
| -void AppListView::Init(const gfx::Rect& bounds) { |
| - model_view_ = new AppListModelView(this); |
| +void AppListView::UpdateBounds() { |
| + if (bubble_style_) |
| + SizeToContents(); |
| + else |
| + GetWidget()->SetBounds(GetFullScreenBounds()); |
| +} |
| + |
| +void AppListView::InitAsFullscreenWidget() { |
| + bubble_style_ = false; |
| + set_background(views::Background::CreateSolidBackground( |
| + kWidgetBackgroundColor)); |
| + |
| + model_view_ = new AppListModelView(this, pagination_model_.get()); |
| model_view_->SetPaintToLayer(true); |
| model_view_->layer()->SetFillsBoundsOpaquely(false); |
| AddChildView(model_view_); |
| @@ -83,7 +125,6 @@ void AppListView::Init(const gfx::Rect& bounds) { |
| views::Widget::InitParams widget_params( |
| views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| widget_params.delegate = this; |
| - widget_params.keep_on_top = true; |
| widget_params.transparent = true; |
| widget_params.parent = Shell::GetInstance()->GetContainer( |
| internal::kShellWindowId_AppListContainer); |
| @@ -91,7 +132,8 @@ void AppListView::Init(const gfx::Rect& bounds) { |
| views::Widget* widget = new views::Widget; |
| widget->Init(widget_params); |
| widget->SetContentsView(this); |
| - widget->SetBounds(bounds); |
| + |
| + widget->SetBounds(GetFullScreenBounds()); |
| // Turns off default animation. |
| widget->SetVisibilityChangedAnimationsEnabled(false); |
| @@ -101,6 +143,39 @@ void AppListView::Init(const gfx::Rect& bounds) { |
| UpdateModel(); |
| } |
| +void AppListView::InitAsBubble() { |
| + bubble_style_ = true; |
| + set_background(NULL); |
| + |
| + SetLayoutManager(new views::BoxLayout( |
| + views::BoxLayout::kVertical, 0, 0, kModelViewFooterPadding)); |
| + |
| + model_view_ = new AppListModelView(this, pagination_model_.get()); |
| + model_view_->SetLayout(kPreferredIconDimension, |
| + kPreferredCols, |
| + kPreferredRows); |
| + AddChildView(model_view_); |
| + |
| + PageSwitcher* page_switcher = new PageSwitcher(pagination_model_.get()); |
| + AddChildView(page_switcher); |
| + |
| + set_anchor_view(Shell::GetInstance()->launcher()->GetAppListButtonView()); |
|
sky
2012/05/06 22:51:15
Is the launcher always visible when we do this?
xiyuan
2012/05/07 16:46:10
Yes, launcher will always be visible. In ShelfLayo
|
| + set_parent_window(Shell::GetInstance()->GetContainer( |
| + internal::kShellWindowId_AppListContainer)); |
| + set_close_on_deactivate(false); |
| + views::BubbleDelegateView::CreateBubble(this); |
| + |
| + // Resets default background since AppListBubbleBorder paints background. |
| + GetBubbleFrameView()->set_background(NULL); |
| + |
| + // Overrides border with AppListBubbleBorder. |
| + bubble_border_ = new AppListBubbleBorder(this); |
| + GetBubbleFrameView()->SetBubbleBorder(bubble_border_); |
| + SizeToContents(); // Recalcuates with new border. |
| + |
| + UpdateModel(); |
| +} |
| + |
| void AppListView::UpdateModel() { |
| if (delegate_.get()) { |
| scoped_ptr<AppListModel> new_model(new AppListModel); |
| @@ -120,19 +195,23 @@ void AppListView::Layout() { |
| if (rect.IsEmpty()) |
| return; |
| - // Gets work area rect, which is in screen coordinates. |
| - gfx::Rect workarea = Shell::GetInstance()->shelf()->IsVisible() ? |
| - ScreenAsh::GetUnmaximizedWorkAreaBounds(GetWidget()->GetNativeView()) : |
| - gfx::Screen::GetMonitorNearestWindow( |
| - GetWidget()->GetNativeView()).work_area(); |
| + if (bubble_style_) { |
| + views::View::Layout(); |
| + } else { |
| + // Gets work area rect, which is in screen coordinates. |
| + gfx::Rect workarea = Shell::GetInstance()->shelf()->IsVisible() ? |
| + ScreenAsh::GetUnmaximizedWorkAreaBounds(GetWidget()->GetNativeView()) : |
| + gfx::Screen::GetMonitorNearestWindow( |
| + GetWidget()->GetNativeView()).work_area(); |
| - // Converts |workarea| into view's coordinates. |
| - gfx::Point origin(workarea.origin()); |
| - views::View::ConvertPointFromScreen(this, &origin); |
| - workarea.Offset(-origin.x(), -origin.y()); |
| + // Converts |workarea| into view's coordinates. |
| + gfx::Point origin(workarea.origin()); |
| + views::View::ConvertPointFromScreen(this, &origin); |
| + workarea.Offset(-origin.x(), -origin.y()); |
| - rect = rect.Intersect(workarea); |
| - model_view_->SetBoundsRect(rect); |
| + rect = rect.Intersect(workarea); |
| + model_view_->SetBoundsRect(rect); |
| + } |
| } |
| bool AppListView::OnKeyPressed(const views::KeyEvent& event) { |
| @@ -145,8 +224,10 @@ bool AppListView::OnKeyPressed(const views::KeyEvent& event) { |
| } |
| bool AppListView::OnMousePressed(const views::MouseEvent& event) { |
| - // If mouse click reaches us, this means user clicks on blank area. So close. |
| - Close(); |
| + // For full screen mode, if mouse click reaches us, this means user clicks |
| + // on blank area. So close. |
| + if (!bubble_style_) |
| + Close(); |
| return true; |
| } |
| @@ -164,4 +245,43 @@ void AppListView::ButtonPressed(views::Button* sender, |
| Close(); |
| } |
| +gfx::Rect AppListView::GetBubbleBounds() { |
| + // This happens before replacing the default border. |
| + if (!bubble_border_) |
| + return views::BubbleDelegateView::GetBubbleBounds(); |
| + |
| + const int old_arrow_offset = bubble_border_->arrow_offset(); |
| + const gfx::Rect anchor_rect = GetAnchorRect(); |
| + |
| + bubble_border_->set_arrow_offset(0); |
| + gfx::Rect bubble_rect = GetBubbleFrameView()->GetUpdatedWindowBounds( |
| + anchor_rect, |
| + GetPreferredSize(), |
| + false /* try_mirroring_arrow */); |
| + |
| + gfx::Rect monitor_rect = gfx::Screen::GetMonitorNearestPoint( |
| + anchor_rect.CenterPoint()).work_area(); |
| + if (monitor_rect.IsEmpty() || monitor_rect.Contains(bubble_rect)) |
| + return bubble_rect; |
| + |
| + int offset = 0; |
| + if (bubble_rect.x() < monitor_rect.x()) |
| + offset = monitor_rect.x() - bubble_rect.x(); |
| + else if (bubble_rect.right() > monitor_rect.right()) |
| + offset = monitor_rect.right() - bubble_rect.right(); |
| + |
| + bubble_rect.set_x(bubble_rect.x() + offset); |
| + |
| + // Moves bubble arrow in the opposite direction. i.e. If bubble bounds is |
| + // moved to right (positive offset), we need to move arrow to left so that |
| + // it points to the same position before the move. |
| + bubble_border_->set_arrow_offset(-offset); |
| + |
| + // Repaints border if arrow offset is changed. |
| + if (bubble_border_->arrow_offset() != old_arrow_offset) |
| + GetBubbleFrameView()->SchedulePaint(); |
| + |
| + return bubble_rect; |
| +} |
| + |
| } // namespace ash |