OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ash/app_list/app_list_view.h" | 5 #include "ui/app_list/app_list_view.h" |
6 | 6 |
7 #include "ash/app_list/app_list.h" | 7 #include <string> |
8 #include "ash/app_list/app_list_bubble_border.h" | 8 |
9 #include "ash/app_list/app_list_item_view.h" | 9 #include "ui/app_list/app_list_bubble_border.h" |
10 #include "ash/app_list/app_list_model.h" | 10 #include "ui/app_list/app_list_item_view.h" |
11 #include "ash/app_list/app_list_model_view.h" | 11 #include "ui/app_list/app_list_model.h" |
12 #include "ash/app_list/app_list_view_delegate.h" | 12 #include "ui/app_list/app_list_model_view.h" |
13 #include "ash/app_list/page_switcher.h" | 13 #include "ui/app_list/app_list_view_delegate.h" |
14 #include "ash/app_list/pagination_model.h" | 14 #include "ui/app_list/page_switcher.h" |
15 #include "ash/launcher/launcher.h" | 15 #include "ui/app_list/pagination_model.h" |
16 #include "ash/screen_ash.h" | |
17 #include "ash/shell.h" | |
18 #include "ash/shell_window_ids.h" | |
19 #include "ash/wm/shelf_layout_manager.h" | |
20 #include "ui/compositor/layer.h" | 16 #include "ui/compositor/layer.h" |
21 #include "ui/compositor/scoped_layer_animation_settings.h" | 17 #include "ui/compositor/scoped_layer_animation_settings.h" |
22 #include "ui/gfx/screen.h" | 18 #include "ui/gfx/screen.h" |
23 #include "ui/gfx/transform_util.h" | 19 #include "ui/gfx/transform_util.h" |
24 #include "ui/views/background.h" | 20 #include "ui/views/background.h" |
25 #include "ui/views/bubble/bubble_frame_view.h" | 21 #include "ui/views/bubble/bubble_frame_view.h" |
26 #include "ui/views/layout/box_layout.h" | 22 #include "ui/views/layout/box_layout.h" |
27 #include "ui/views/widget/widget.h" | 23 #include "ui/views/widget/widget.h" |
28 | 24 |
29 namespace ash { | 25 namespace app_list { |
30 | 26 |
31 namespace { | 27 namespace { |
32 | 28 |
33 // 0.2 black | 29 // 0.2 black |
34 const SkColor kWidgetBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); | 30 const SkColor kWidgetBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); |
35 | 31 |
36 const float kModelViewAnimationScaleFactor = 0.9f; | 32 const float kModelViewAnimationScaleFactor = 0.9f; |
37 | 33 |
38 const int kPreferredIconDimension = 48; | 34 const int kPreferredIconDimension = 48; |
39 const int kPreferredCols = 4; | 35 const int kPreferredCols = 4; |
40 const int kPreferredRows = 4; | 36 const int kPreferredRows = 4; |
41 // Padding space in pixels between model view and page switcher footer. | 37 // Padding space in pixels between model view and page switcher footer. |
42 const int kModelViewFooterPadding = 10; | 38 const int kModelViewFooterPadding = 10; |
43 | 39 |
44 ui::Transform GetScaleTransform(AppListModelView* model_view) { | 40 ui::Transform GetScaleTransform(AppListModelView* model_view) { |
45 gfx::Rect pixel_bounds = model_view->GetLayerBoundsInPixel(); | 41 gfx::Rect pixel_bounds = model_view->GetLayerBoundsInPixel(); |
46 gfx::Point center(pixel_bounds.width() / 2, pixel_bounds.height() / 2); | 42 gfx::Point center(pixel_bounds.width() / 2, pixel_bounds.height() / 2); |
47 return ui::GetScaleTransform(center, kModelViewAnimationScaleFactor); | 43 return ui::GetScaleTransform(center, kModelViewAnimationScaleFactor); |
48 } | 44 } |
49 | 45 |
50 // Bounds returned is used for full screen mode. Use full monitor rect so that | |
51 // the app list shade goes behind the launcher. | |
52 gfx::Rect GetFullScreenBounds() { | |
53 gfx::Point cursor = gfx::Screen::GetCursorScreenPoint(); | |
54 return gfx::Screen::GetMonitorNearestPoint(cursor).bounds(); | |
55 } | |
56 | |
57 } // namespace | 46 } // namespace |
58 | 47 |
59 //////////////////////////////////////////////////////////////////////////////// | 48 //////////////////////////////////////////////////////////////////////////////// |
60 // AppListView: | 49 // AppListView: |
61 | 50 |
62 AppListView::AppListView(AppListViewDelegate* delegate) | 51 AppListView::AppListView(AppListViewDelegate* delegate) |
63 : delegate_(delegate), | 52 : delegate_(delegate), |
64 pagination_model_(new PaginationModel), | 53 pagination_model_(new PaginationModel), |
65 bubble_style_(false), | 54 bubble_style_(false), |
66 bubble_border_(NULL), | 55 bubble_border_(NULL), |
67 model_view_(NULL) { | 56 model_view_(NULL) { |
68 if (internal::AppList::UseAppListV2()) | |
69 InitAsBubble(); | |
70 else | |
71 InitAsFullscreenWidget(); | |
72 } | 57 } |
73 | 58 |
74 AppListView::~AppListView() { | 59 AppListView::~AppListView() { |
75 // Model is going away, so set to NULL before superclass deletes child views. | 60 // Model is going away, so set to NULL before superclass deletes child views. |
76 if (model_view_) | 61 if (model_view_) |
77 model_view_->SetModel(NULL); | 62 model_view_->SetModel(NULL); |
78 } | 63 } |
79 | 64 |
80 void AppListView::AnimateShow(int duration_ms) { | 65 void AppListView::InitAsFullscreenWidget(gfx::NativeView parent, |
81 if (bubble_style_) | 66 const gfx::Rect& screen_bounds, |
82 return; | 67 const gfx::Rect& work_area) { |
83 | |
84 ui::Layer* layer = model_view_->layer(); | |
85 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | |
86 animation.SetTransitionDuration( | |
87 base::TimeDelta::FromMilliseconds(duration_ms)); | |
88 animation.SetTweenType(ui::Tween::EASE_OUT); | |
89 model_view_->SetTransform(ui::Transform()); | |
90 } | |
91 | |
92 void AppListView::AnimateHide(int duration_ms) { | |
93 if (bubble_style_) | |
94 return; | |
95 | |
96 ui::Layer* layer = model_view_->layer(); | |
97 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | |
98 animation.SetTransitionDuration( | |
99 base::TimeDelta::FromMilliseconds(duration_ms)); | |
100 animation.SetTweenType(ui::Tween::EASE_IN); | |
101 model_view_->SetTransform(GetScaleTransform(model_view_)); | |
102 } | |
103 | |
104 void AppListView::Close() { | |
105 if (GetWidget()->IsVisible()) | |
106 Shell::GetInstance()->ToggleAppList(); | |
107 } | |
108 | |
109 void AppListView::UpdateBounds() { | |
110 if (bubble_style_) | |
111 SizeToContents(); | |
112 else | |
113 GetWidget()->SetBounds(GetFullScreenBounds()); | |
114 } | |
115 | |
116 void AppListView::InitAsFullscreenWidget() { | |
117 bubble_style_ = false; | 68 bubble_style_ = false; |
118 set_background(views::Background::CreateSolidBackground( | 69 set_background(views::Background::CreateSolidBackground( |
119 kWidgetBackgroundColor)); | 70 kWidgetBackgroundColor)); |
| 71 work_area_ = work_area; |
120 | 72 |
121 model_view_ = new AppListModelView(this, pagination_model_.get()); | 73 model_view_ = new AppListModelView(this, pagination_model_.get()); |
122 model_view_->SetPaintToLayer(true); | 74 model_view_->SetPaintToLayer(true); |
123 model_view_->layer()->SetFillsBoundsOpaquely(false); | 75 model_view_->layer()->SetFillsBoundsOpaquely(false); |
124 AddChildView(model_view_); | 76 AddChildView(model_view_); |
125 | 77 |
126 views::Widget::InitParams widget_params( | 78 views::Widget::InitParams widget_params( |
127 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | 79 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
128 widget_params.delegate = this; | 80 widget_params.delegate = this; |
129 widget_params.transparent = true; | 81 widget_params.transparent = true; |
130 widget_params.parent = Shell::GetInstance()->GetContainer( | 82 widget_params.parent = parent; |
131 internal::kShellWindowId_AppListContainer); | |
132 | 83 |
133 views::Widget* widget = new views::Widget; | 84 views::Widget* widget = new views::Widget; |
134 widget->Init(widget_params); | 85 widget->Init(widget_params); |
135 widget->SetContentsView(this); | 86 widget->SetContentsView(this); |
136 | 87 widget->SetBounds(screen_bounds); |
137 widget->SetBounds(GetFullScreenBounds()); | |
138 | 88 |
139 // Turns off default animation. | 89 // Turns off default animation. |
140 widget->SetVisibilityChangedAnimationsEnabled(false); | 90 widget->SetVisibilityChangedAnimationsEnabled(false); |
141 | 91 |
142 // Sets initial transform. AnimateShow changes it back to identity transform. | 92 // Sets initial transform. AnimateShow changes it back to identity transform. |
143 model_view_->SetTransform(GetScaleTransform(model_view_)); | 93 model_view_->SetTransform(GetScaleTransform(model_view_)); |
144 UpdateModel(); | 94 UpdateModel(); |
145 } | 95 } |
146 | 96 |
147 void AppListView::InitAsBubble() { | 97 void AppListView::InitAsBubble(gfx::NativeView parent, views::View* anchor) { |
148 bubble_style_ = true; | 98 bubble_style_ = true; |
149 set_background(NULL); | 99 set_background(NULL); |
150 | 100 |
151 SetLayoutManager(new views::BoxLayout( | 101 SetLayoutManager(new views::BoxLayout( |
152 views::BoxLayout::kVertical, 0, 0, kModelViewFooterPadding)); | 102 views::BoxLayout::kVertical, 0, 0, kModelViewFooterPadding)); |
153 | 103 |
154 model_view_ = new AppListModelView(this, pagination_model_.get()); | 104 model_view_ = new AppListModelView(this, pagination_model_.get()); |
155 model_view_->SetLayout(kPreferredIconDimension, | 105 model_view_->SetLayout(kPreferredIconDimension, |
156 kPreferredCols, | 106 kPreferredCols, |
157 kPreferredRows); | 107 kPreferredRows); |
158 AddChildView(model_view_); | 108 AddChildView(model_view_); |
159 | 109 |
160 PageSwitcher* page_switcher = new PageSwitcher(pagination_model_.get()); | 110 PageSwitcher* page_switcher = new PageSwitcher(pagination_model_.get()); |
161 AddChildView(page_switcher); | 111 AddChildView(page_switcher); |
162 | 112 |
163 set_anchor_view(Shell::GetInstance()->launcher()->GetAppListButtonView()); | 113 set_anchor_view(anchor); |
164 set_parent_window(Shell::GetInstance()->GetContainer( | 114 set_parent_window(parent); |
165 internal::kShellWindowId_AppListContainer)); | |
166 set_close_on_deactivate(false); | 115 set_close_on_deactivate(false); |
167 views::BubbleDelegateView::CreateBubble(this); | 116 views::BubbleDelegateView::CreateBubble(this); |
168 | 117 |
169 // Resets default background since AppListBubbleBorder paints background. | 118 // Resets default background since AppListBubbleBorder paints background. |
170 GetBubbleFrameView()->set_background(NULL); | 119 GetBubbleFrameView()->set_background(NULL); |
171 | 120 |
172 // Overrides border with AppListBubbleBorder. | 121 // Overrides border with AppListBubbleBorder. |
173 bubble_border_ = new AppListBubbleBorder(this); | 122 bubble_border_ = new AppListBubbleBorder(this); |
174 GetBubbleFrameView()->SetBubbleBorder(bubble_border_); | 123 GetBubbleFrameView()->SetBubbleBorder(bubble_border_); |
175 SizeToContents(); // Recalcuates with new border. | 124 SizeToContents(); // Recalcuates with new border. |
176 | 125 |
177 UpdateModel(); | 126 UpdateModel(); |
178 } | 127 } |
179 | 128 |
| 129 void AppListView::AnimateShow(int duration_ms) { |
| 130 if (bubble_style_) |
| 131 return; |
| 132 |
| 133 ui::Layer* layer = model_view_->layer(); |
| 134 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| 135 animation.SetTransitionDuration( |
| 136 base::TimeDelta::FromMilliseconds(duration_ms)); |
| 137 animation.SetTweenType(ui::Tween::EASE_OUT); |
| 138 model_view_->SetTransform(ui::Transform()); |
| 139 } |
| 140 |
| 141 void AppListView::AnimateHide(int duration_ms) { |
| 142 if (bubble_style_) |
| 143 return; |
| 144 |
| 145 ui::Layer* layer = model_view_->layer(); |
| 146 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| 147 animation.SetTransitionDuration( |
| 148 base::TimeDelta::FromMilliseconds(duration_ms)); |
| 149 animation.SetTweenType(ui::Tween::EASE_IN); |
| 150 model_view_->SetTransform(GetScaleTransform(model_view_)); |
| 151 } |
| 152 |
| 153 void AppListView::Close() { |
| 154 if (delegate_.get()) |
| 155 delegate_->Close(); |
| 156 else |
| 157 GetWidget()->Close(); |
| 158 } |
| 159 |
| 160 void AppListView::UpdateBounds(const gfx::Rect& screen_bounds, |
| 161 const gfx::Rect& work_area) { |
| 162 if (bubble_style_) { |
| 163 SizeToContents(); |
| 164 } else { |
| 165 work_area_ = work_area; |
| 166 GetWidget()->SetBounds(screen_bounds); |
| 167 } |
| 168 } |
| 169 |
180 void AppListView::UpdateModel() { | 170 void AppListView::UpdateModel() { |
181 if (delegate_.get()) { | 171 if (delegate_.get()) { |
182 scoped_ptr<AppListModel> new_model(new AppListModel); | 172 scoped_ptr<AppListModel> new_model(new AppListModel); |
183 delegate_->SetModel(new_model.get()); | 173 delegate_->SetModel(new_model.get()); |
184 delegate_->UpdateModel(std::string()); | 174 delegate_->UpdateModel(std::string()); |
185 model_view_->SetModel(new_model.get()); | 175 model_view_->SetModel(new_model.get()); |
186 model_.reset(new_model.release()); | 176 model_.reset(new_model.release()); |
187 } | 177 } |
188 } | 178 } |
189 | 179 |
190 views::View* AppListView::GetInitiallyFocusedView() { | 180 views::View* AppListView::GetInitiallyFocusedView() { |
191 return model_view_; | 181 return model_view_; |
192 } | 182 } |
193 | 183 |
194 void AppListView::Layout() { | 184 void AppListView::Layout() { |
195 gfx::Rect rect(GetContentsBounds()); | 185 gfx::Rect rect(GetContentsBounds()); |
196 if (rect.IsEmpty()) | 186 if (rect.IsEmpty()) |
197 return; | 187 return; |
198 | 188 |
199 if (bubble_style_) { | 189 if (bubble_style_) { |
200 views::View::Layout(); | 190 views::View::Layout(); |
201 } else { | 191 } else { |
202 // Gets work area rect, which is in screen coordinates. | 192 // Gets work area rect, which is in screen coordinates. |
203 gfx::Rect workarea = Shell::GetInstance()->shelf()->IsVisible() ? | 193 gfx::Rect workarea(work_area_); |
204 ScreenAsh::GetUnmaximizedWorkAreaBounds(GetWidget()->GetNativeView()) : | |
205 gfx::Screen::GetMonitorNearestWindow( | |
206 GetWidget()->GetNativeView()).work_area(); | |
207 | 194 |
208 // Converts |workarea| into view's coordinates. | 195 // Converts |workarea| into view's coordinates. |
209 gfx::Point origin(workarea.origin()); | 196 gfx::Point origin(workarea.origin()); |
210 views::View::ConvertPointFromScreen(this, &origin); | 197 views::View::ConvertPointFromScreen(this, &origin); |
211 workarea.Offset(-origin.x(), -origin.y()); | 198 workarea.Offset(-origin.x(), -origin.y()); |
212 | 199 |
213 rect = rect.Intersect(workarea); | 200 rect = rect.Intersect(workarea); |
214 model_view_->SetBoundsRect(rect); | 201 model_view_->SetBoundsRect(rect); |
215 } | 202 } |
216 } | 203 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // it points to the same position before the move. | 265 // it points to the same position before the move. |
279 bubble_border_->set_arrow_offset(-offset); | 266 bubble_border_->set_arrow_offset(-offset); |
280 | 267 |
281 // Repaints border if arrow offset is changed. | 268 // Repaints border if arrow offset is changed. |
282 if (bubble_border_->arrow_offset() != old_arrow_offset) | 269 if (bubble_border_->arrow_offset() != old_arrow_offset) |
283 GetBubbleFrameView()->SchedulePaint(); | 270 GetBubbleFrameView()->SchedulePaint(); |
284 | 271 |
285 return bubble_rect; | 272 return bubble_rect; |
286 } | 273 } |
287 | 274 |
288 } // namespace ash | 275 } // namespace app_list |
OLD | NEW |