| 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 |