OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "athena/home/home_card_view.h" | |
6 | |
7 #include "athena/home/home_card_constants.h" | |
8 #include "athena/util/athena_constants.h" | |
9 #include "athena/wm/public/window_manager.h" | |
10 #include "ui/app_list/app_list_view_delegate.h" | |
11 #include "ui/app_list/views/app_list_main_view.h" | |
12 #include "ui/app_list/views/contents_view.h" | |
13 #include "ui/app_list/views/search_box_view.h" | |
14 #include "ui/aura/window.h" | |
15 #include "ui/compositor/closure_animation_observer.h" | |
16 #include "ui/compositor/scoped_layer_animation_settings.h" | |
17 #include "ui/views/background.h" | |
18 #include "ui/views/focus/focus_manager.h" | |
19 #include "ui/views/widget/widget.h" | |
20 | |
21 namespace athena { | |
22 | |
23 namespace { | |
24 | |
25 const float kMinimizedHomeOpacity = 0.65f; | |
26 const int kIndicatorOffset = 24; | |
27 const int kAppListOffset = -128; | |
28 } | |
29 | |
30 HomeCardView::HomeCardView(app_list::AppListViewDelegate* view_delegate, | |
31 HomeCardGestureManager::Delegate* gesture_delegate) | |
32 : background_(new views::View), | |
33 main_view_(new app_list::AppListMainView(view_delegate)), | |
34 search_box_view_(new app_list::SearchBoxView(main_view_, view_delegate)), | |
35 minimized_background_(new views::View()), | |
36 drag_indicator_(new views::View()), | |
37 gesture_delegate_(gesture_delegate), | |
38 weak_factory_(this) { | |
39 background_->set_background( | |
40 views::Background::CreateVerticalGradientBackground(SK_ColorLTGRAY, | |
41 SK_ColorWHITE)); | |
42 background_->SetPaintToLayer(true); | |
43 background_->SetFillsBoundsOpaquely(false); | |
44 AddChildView(background_); | |
45 | |
46 main_view_->SetPaintToLayer(true); | |
47 main_view_->SetFillsBoundsOpaquely(false); | |
48 main_view_->layer()->SetMasksToBounds(true); | |
49 AddChildView(main_view_); | |
50 | |
51 search_box_view_->SetPaintToLayer(true); | |
52 search_box_view_->SetFillsBoundsOpaquely(false); | |
53 search_box_view_->layer()->SetMasksToBounds(true); | |
54 AddChildView(search_box_view_); | |
55 | |
56 minimized_background_->set_background( | |
57 views::Background::CreateSolidBackground( | |
58 SkColorSetA(SK_ColorBLACK, 256 * kMinimizedHomeOpacity))); | |
59 minimized_background_->SetPaintToLayer(true); | |
60 minimized_background_->SetFillsBoundsOpaquely(false); | |
61 minimized_background_->layer()->set_name("MinimizedBackground"); | |
62 AddChildView(minimized_background_); | |
63 | |
64 drag_indicator_->set_background( | |
65 views::Background::CreateSolidBackground(SK_ColorWHITE)); | |
66 drag_indicator_->SetPaintToLayer(true); | |
67 AddChildView(drag_indicator_); | |
68 } | |
69 | |
70 HomeCardView::~HomeCardView() { | |
71 } | |
72 | |
73 void HomeCardView::Init() { | |
74 main_view_->Init(GetWidget()->GetNativeView(), | |
75 -1, /* inital apps page: -1 means default */ | |
76 search_box_view_); | |
77 } | |
78 | |
79 void HomeCardView::SetStateProgress(HomeCard::State from_state, | |
80 HomeCard::State to_state, | |
81 float progress) { | |
82 // TODO(mukai): not clear the focus, but simply close the virtual keyboard. | |
83 GetFocusManager()->ClearFocus(); | |
84 | |
85 gfx::Rect from_main_bounds = GetMainViewBounds(from_state); | |
86 gfx::Rect to_main_bounds = GetMainViewBounds(to_state); | |
87 if (from_main_bounds != to_main_bounds) { | |
88 DCHECK_EQ(from_main_bounds.size().ToString(), | |
89 to_main_bounds.size().ToString()); | |
90 gfx::Rect main_bounds = gfx::Tween::RectValueBetween( | |
91 progress, from_main_bounds, to_main_bounds); | |
92 main_view_->SetBoundsRect(main_bounds); | |
93 main_bounds.set_height( | |
94 search_box_view_->GetHeightForWidth(main_bounds.width())); | |
95 search_box_view_->SetBoundsRect(main_bounds); | |
96 } | |
97 | |
98 float background_opacity = 1.0f; | |
99 if (from_state == HomeCard::VISIBLE_MINIMIZED || | |
100 to_state == HomeCard::VISIBLE_MINIMIZED) { | |
101 background_opacity = (from_state == HomeCard::VISIBLE_MINIMIZED) | |
102 ? progress | |
103 : (1.0f - progress); | |
104 } | |
105 background_->layer()->SetOpacity(background_opacity); | |
106 minimized_background_->layer()->SetOpacity(1.0f - background_opacity); | |
107 UpdateMinimizedBackgroundVisibility(); | |
108 | |
109 int background_height = kHomeCardHeight; | |
110 if (from_state == HomeCard::VISIBLE_CENTERED || | |
111 to_state == HomeCard::VISIBLE_CENTERED) { | |
112 gfx::Rect window_bounds = GetWidget()->GetWindowBoundsInScreen(); | |
113 background_height = window_bounds.height() - window_bounds.y(); | |
114 } | |
115 gfx::Transform background_transform; | |
116 background_transform.Scale(SK_MScalar1, SkIntToMScalar(background_height) / | |
117 SkIntToMScalar(height())); | |
118 background_->layer()->SetTransform(background_transform); | |
119 | |
120 gfx::Rect from_bounds = GetDragIndicatorBounds(from_state); | |
121 gfx::Rect to_bounds = GetDragIndicatorBounds(to_state); | |
122 if (from_bounds != to_bounds) { | |
123 DCHECK_EQ(from_bounds.size().ToString(), to_bounds.size().ToString()); | |
124 drag_indicator_->SetBoundsRect( | |
125 gfx::Tween::RectValueBetween(progress, from_bounds, to_bounds)); | |
126 } | |
127 } | |
128 | |
129 void HomeCardView::SetStateWithAnimation( | |
130 HomeCard::State state, | |
131 gfx::Tween::Type tween_type, | |
132 const base::Closure& on_animation_ended) { | |
133 float minimized_opacity = | |
134 (state == HomeCard::VISIBLE_MINIMIZED) ? 1.0f : 0.0f; | |
135 // |minimized_background_| needs to be visible before scheduling animation. | |
136 if (state == HomeCard::VISIBLE_MINIMIZED) | |
137 minimized_background_->SetVisible(true); | |
138 | |
139 if (minimized_opacity != minimized_background_->layer()->GetTargetOpacity()) { | |
140 ui::ScopedLayerAnimationSettings settings( | |
141 minimized_background_->layer()->GetAnimator()); | |
142 settings.SetTweenType(gfx::Tween::EASE_IN); | |
143 settings.AddObserver(new ui::ClosureAnimationObserver( | |
144 base::Bind(&HomeCardView::UpdateMinimizedBackgroundVisibility, | |
145 weak_factory_.GetWeakPtr()))); | |
146 minimized_background_->layer()->SetOpacity(minimized_opacity); | |
147 } | |
148 | |
149 gfx::Transform background_transform; | |
150 if (state != HomeCard::VISIBLE_CENTERED) { | |
151 background_transform.Scale(SK_MScalar1, SkIntToMScalar(kHomeCardHeight) / | |
152 SkIntToMScalar(height())); | |
153 } | |
154 float background_opacity = 1.0f - minimized_opacity; | |
155 if (background_->layer()->GetTargetTransform() != background_transform || | |
156 background_->layer()->GetTargetOpacity() != background_opacity) { | |
157 ui::ScopedLayerAnimationSettings settings( | |
158 background_->layer()->GetAnimator()); | |
159 settings.SetTweenType(tween_type); | |
160 background_->layer()->SetTransform(background_transform); | |
161 background_->layer()->SetOpacity(background_opacity); | |
162 } | |
163 | |
164 { | |
165 ui::ScopedLayerAnimationSettings settings( | |
166 drag_indicator_->layer()->GetAnimator()); | |
167 settings.SetTweenType(tween_type); | |
168 drag_indicator_->SetBoundsRect(GetDragIndicatorBounds(state)); | |
169 } | |
170 | |
171 { | |
172 ui::ScopedLayerAnimationSettings settings( | |
173 main_view_->layer()->GetAnimator()); | |
174 settings.SetTweenType(tween_type); | |
175 settings.AddObserver(new ui::ClosureAnimationObserver(on_animation_ended)); | |
176 gfx::Rect main_bounds = GetMainViewBounds(state); | |
177 main_view_->SetBoundsRect(main_bounds); | |
178 main_bounds.set_height( | |
179 search_box_view_->GetHeightForWidth(main_bounds.width())); | |
180 search_box_view_->SetBoundsRect(main_bounds); | |
181 } | |
182 | |
183 if (state == HomeCard::VISIBLE_BOTTOM) { | |
184 app_list::ContentsView* contents_view = main_view_->contents_view(); | |
185 contents_view->SetActivePage(contents_view->GetPageIndexForState( | |
186 app_list::AppListModel::STATE_START)); | |
187 } | |
188 } | |
189 | |
190 void HomeCardView::ClearGesture() { | |
191 gesture_manager_.reset(); | |
192 } | |
193 | |
194 void HomeCardView::OnGestureEvent(ui::GestureEvent* event) { | |
195 if (!gesture_manager_ && event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | |
196 gesture_manager_.reset(new HomeCardGestureManager( | |
197 gesture_delegate_, | |
198 GetWidget()->GetNativeWindow()->GetRootWindow()->bounds())); | |
199 } | |
200 | |
201 if (gesture_manager_) | |
202 gesture_manager_->ProcessGestureEvent(event); | |
203 } | |
204 | |
205 bool HomeCardView::OnMousePressed(const ui::MouseEvent& event) { | |
206 if (HomeCard::Get()->GetState() == HomeCard::VISIBLE_MINIMIZED && | |
207 event.IsLeftMouseButton() && event.GetClickCount() == 1) { | |
208 athena::WindowManager::Get()->EnterOverview(); | |
209 return true; | |
210 } | |
211 return false; | |
212 } | |
213 | |
214 void HomeCardView::Layout() { | |
215 const gfx::Rect contents_bounds = GetContentsBounds(); | |
216 background_->SetBoundsRect(contents_bounds); | |
217 minimized_background_->SetBoundsRect(contents_bounds); | |
218 const gfx::Rect drag_indicator_bounds = | |
219 GetDragIndicatorBounds(HomeCard::Get()->GetState()); | |
220 drag_indicator_->SetBoundsRect(drag_indicator_bounds); | |
221 | |
222 gfx::Rect main_bounds(GetMainViewBounds(HomeCard::Get()->GetState())); | |
223 main_view_->SetBoundsRect(main_bounds); | |
224 | |
225 main_bounds.set_height( | |
226 search_box_view_->GetHeightForWidth(main_bounds.width())); | |
227 search_box_view_->SetBoundsRect(main_bounds); | |
228 } | |
229 | |
230 gfx::Rect HomeCardView::GetDragIndicatorBounds(HomeCard::State state) { | |
231 gfx::Rect drag_indicator_bounds( | |
232 GetContentsBounds().CenterPoint().x() - kHomeCardDragIndicatorWidth / 2, | |
233 kHomeCardDragIndicatorMarginHeight, kHomeCardDragIndicatorWidth, | |
234 kHomeCardDragIndicatorHeight); | |
235 if (state == HomeCard::VISIBLE_CENTERED) | |
236 drag_indicator_bounds.Offset(0, kSystemUIHeight); | |
237 return drag_indicator_bounds; | |
238 } | |
239 | |
240 gfx::Rect HomeCardView::GetMainViewBounds(HomeCard::State state) { | |
241 const gfx::Rect contents_bounds = GetContentsBounds(); | |
242 const int main_width = main_view_->GetPreferredSize().width(); | |
243 gfx::Rect main_bounds( | |
244 contents_bounds.CenterPoint().x() - main_width / 2, | |
245 GetDragIndicatorBounds(state).bottom() + kIndicatorOffset, main_width, | |
246 contents_bounds.height()); | |
247 // This is a bit hacky but slightly shifting up the main_view to fit | |
248 // the search box and app icons in the home card. | |
249 if (state != HomeCard::VISIBLE_CENTERED) | |
250 main_bounds.set_y(kAppListOffset); | |
251 return main_bounds; | |
252 } | |
253 | |
254 void HomeCardView::UpdateMinimizedBackgroundVisibility() { | |
255 minimized_background_->SetVisible( | |
256 minimized_background_->layer()->GetTargetOpacity() != 0.0f); | |
257 } | |
258 | |
259 views::View* HomeCardView::GetContentsView() { | |
260 return this; | |
261 } | |
262 | |
263 } // namespace athena | |
OLD | NEW |