| 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 "ui/app_list/app_list_view.h" | 5 #include "ui/app_list/app_list_view.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 |
| 9 #include "ui/app_list/app_list_bubble_border.h" | 10 #include "ui/app_list/app_list_bubble_border.h" |
| 10 #include "ui/app_list/app_list_item_view.h" | 11 #include "ui/app_list/app_list_item_view.h" |
| 11 #include "ui/app_list/app_list_model.h" | 12 #include "ui/app_list/app_list_model.h" |
| 12 #include "ui/app_list/app_list_model_view.h" | |
| 13 #include "ui/app_list/app_list_view_delegate.h" | 13 #include "ui/app_list/app_list_view_delegate.h" |
| 14 #include "ui/app_list/apps_grid_view.h" |
| 14 #include "ui/app_list/page_switcher.h" | 15 #include "ui/app_list/page_switcher.h" |
| 15 #include "ui/app_list/pagination_model.h" | 16 #include "ui/app_list/pagination_model.h" |
| 17 #include "ui/app_list/search_box_model.h" |
| 18 #include "ui/app_list/search_box_view.h" |
| 19 #include "ui/app_list/search_result_list_view.h" |
| 16 #include "ui/compositor/layer.h" | 20 #include "ui/compositor/layer.h" |
| 17 #include "ui/compositor/scoped_layer_animation_settings.h" | 21 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 18 #include "ui/gfx/screen.h" | 22 #include "ui/gfx/screen.h" |
| 19 #include "ui/gfx/transform_util.h" | 23 #include "ui/gfx/transform_util.h" |
| 20 #include "ui/views/background.h" | 24 #include "ui/views/background.h" |
| 21 #include "ui/views/bubble/bubble_frame_view.h" | 25 #include "ui/views/bubble/bubble_frame_view.h" |
| 22 #include "ui/views/layout/box_layout.h" | 26 #include "ui/views/controls/textfield/textfield.h" |
| 23 #include "ui/views/widget/widget.h" | 27 #include "ui/views/widget/widget.h" |
| 24 | 28 |
| 25 namespace app_list { | 29 namespace app_list { |
| 26 | 30 |
| 27 namespace { | 31 namespace { |
| 28 | 32 |
| 29 // 0.2 black | 33 // 0.2 black |
| 30 const SkColor kWidgetBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); | 34 const SkColor kWidgetBackgroundColor = SkColorSetARGB(0x33, 0, 0, 0); |
| 31 | 35 |
| 32 const float kModelViewAnimationScaleFactor = 0.9f; | 36 const float kModelViewAnimationScaleFactor = 0.9f; |
| 33 | 37 |
| 38 const int kPreferredWidth = 360; |
| 39 |
| 34 const int kPreferredIconDimension = 48; | 40 const int kPreferredIconDimension = 48; |
| 35 const int kPreferredCols = 4; | 41 const int kPreferredCols = 4; |
| 36 const int kPreferredRows = 4; | 42 const int kPreferredRows = 4; |
| 37 | 43 |
| 38 ui::Transform GetScaleTransform(AppListModelView* model_view) { | 44 // Inner padding space in pixels of bubble contents. |
| 45 const int kInnerPadding = 1; |
| 46 |
| 47 ui::Transform GetScaleTransform(AppsGridView* model_view) { |
| 39 gfx::Rect pixel_bounds = model_view->GetLayerBoundsInPixel(); | 48 gfx::Rect pixel_bounds = model_view->GetLayerBoundsInPixel(); |
| 40 gfx::Point center(pixel_bounds.width() / 2, pixel_bounds.height() / 2); | 49 gfx::Point center(pixel_bounds.width() / 2, pixel_bounds.height() / 2); |
| 41 return ui::GetScaleTransform(center, kModelViewAnimationScaleFactor); | 50 return ui::GetScaleTransform(center, kModelViewAnimationScaleFactor); |
| 42 } | 51 } |
| 43 | 52 |
| 44 } // namespace | 53 } // namespace |
| 45 | 54 |
| 46 //////////////////////////////////////////////////////////////////////////////// | 55 //////////////////////////////////////////////////////////////////////////////// |
| 47 // AppListView: | 56 // AppListView: |
| 48 | 57 |
| 49 AppListView::AppListView(AppListViewDelegate* delegate) | 58 AppListView::AppListView(AppListViewDelegate* delegate) |
| 50 : delegate_(delegate), | 59 : delegate_(delegate), |
| 51 pagination_model_(new PaginationModel), | 60 pagination_model_(new PaginationModel), |
| 52 bubble_style_(false), | 61 bubble_style_(false), |
| 53 bubble_border_(NULL), | 62 bubble_border_(NULL), |
| 54 model_view_(NULL) { | 63 apps_view_(NULL), |
| 64 page_switcher_view_(NULL), |
| 65 search_box_view_(NULL), |
| 66 search_results_view_(NULL) { |
| 55 } | 67 } |
| 56 | 68 |
| 57 AppListView::~AppListView() { | 69 AppListView::~AppListView() { |
| 58 // Deletes all child views while the models are still valid. | 70 // Deletes all child views while the models are still valid. |
| 59 RemoveAllChildViews(true); | 71 RemoveAllChildViews(true); |
| 60 } | 72 } |
| 61 | 73 |
| 62 void AppListView::InitAsFullscreenWidget(gfx::NativeView parent, | 74 void AppListView::InitAsFullscreenWidget(gfx::NativeView parent, |
| 63 const gfx::Rect& screen_bounds, | 75 const gfx::Rect& screen_bounds, |
| 64 const gfx::Rect& work_area) { | 76 const gfx::Rect& work_area) { |
| 65 bubble_style_ = false; | 77 bubble_style_ = false; |
| 66 set_background(views::Background::CreateSolidBackground( | 78 set_background(views::Background::CreateSolidBackground( |
| 67 kWidgetBackgroundColor)); | 79 kWidgetBackgroundColor)); |
| 68 work_area_ = work_area; | 80 work_area_ = work_area; |
| 69 | 81 |
| 70 model_view_ = new AppListModelView(this, pagination_model_.get()); | 82 apps_view_ = new AppsGridView(this, pagination_model_.get()); |
| 71 model_view_->SetPaintToLayer(true); | 83 apps_view_->SetPaintToLayer(true); |
| 72 model_view_->layer()->SetFillsBoundsOpaquely(false); | 84 apps_view_->layer()->SetFillsBoundsOpaquely(false); |
| 73 AddChildView(model_view_); | 85 AddChildView(apps_view_); |
| 74 | 86 |
| 75 views::Widget::InitParams widget_params( | 87 views::Widget::InitParams widget_params( |
| 76 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | 88 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
| 77 widget_params.delegate = this; | 89 widget_params.delegate = this; |
| 78 widget_params.transparent = true; | 90 widget_params.transparent = true; |
| 79 widget_params.parent = parent; | 91 widget_params.parent = parent; |
| 80 | 92 |
| 81 views::Widget* widget = new views::Widget; | 93 views::Widget* widget = new views::Widget; |
| 82 widget->Init(widget_params); | 94 widget->Init(widget_params); |
| 83 widget->SetContentsView(this); | 95 widget->SetContentsView(this); |
| 84 widget->SetBounds(screen_bounds); | 96 widget->SetBounds(screen_bounds); |
| 85 | 97 |
| 86 // Turns off default animation. | 98 // Turns off default animation. |
| 87 widget->SetVisibilityChangedAnimationsEnabled(false); | 99 widget->SetVisibilityChangedAnimationsEnabled(false); |
| 88 | 100 |
| 89 // Sets initial transform. AnimateShow changes it back to identity transform. | 101 // Sets initial transform. AnimateShow changes it back to identity transform. |
| 90 model_view_->SetTransform(GetScaleTransform(model_view_)); | 102 apps_view_->SetTransform(GetScaleTransform(apps_view_)); |
| 91 UpdateModel(); | 103 CreateModel(); |
| 92 } | 104 } |
| 93 | 105 |
| 94 void AppListView::InitAsBubble(gfx::NativeView parent, views::View* anchor) { | 106 void AppListView::InitAsBubble(gfx::NativeView parent, views::View* anchor) { |
| 95 bubble_style_ = true; | 107 bubble_style_ = true; |
| 96 set_background(NULL); | 108 set_background(NULL); |
| 97 | 109 |
| 98 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 110 search_box_view_ = new SearchBoxView(this); |
| 111 AddChildView(search_box_view_); |
| 99 | 112 |
| 100 model_view_ = new AppListModelView(this, pagination_model_.get()); | 113 apps_view_ = new AppsGridView(this, pagination_model_.get()); |
| 101 model_view_->SetLayout(kPreferredIconDimension, | 114 apps_view_->SetLayout(kPreferredIconDimension, |
| 102 kPreferredCols, | 115 kPreferredCols, |
| 103 kPreferredRows); | 116 kPreferredRows); |
| 104 AddChildView(model_view_); | 117 AddChildView(apps_view_); |
| 105 | 118 |
| 106 PageSwitcher* page_switcher = new PageSwitcher(pagination_model_.get()); | 119 search_results_view_ = new SearchResultListView(this); |
| 107 AddChildView(page_switcher); | 120 search_results_view_->SetVisible(false); |
| 121 AddChildView(search_results_view_); |
| 122 |
| 123 page_switcher_view_ = new PageSwitcher(pagination_model_.get()); |
| 124 AddChildView(page_switcher_view_); |
| 125 |
| 126 search_box_view_->set_grid_view(apps_view_); |
| 127 search_box_view_->set_results_view(search_results_view_); |
| 108 | 128 |
| 109 set_anchor_view(anchor); | 129 set_anchor_view(anchor); |
| 130 set_margin(0); |
| 110 set_parent_window(parent); | 131 set_parent_window(parent); |
| 111 set_close_on_deactivate(false); | 132 set_close_on_deactivate(false); |
| 112 views::BubbleDelegateView::CreateBubble(this); | 133 views::BubbleDelegateView::CreateBubble(this); |
| 113 | 134 |
| 114 // Resets default background since AppListBubbleBorder paints background. | 135 // Resets default background since AppListBubbleBorder paints background. |
| 115 GetBubbleFrameView()->set_background(NULL); | 136 GetBubbleFrameView()->set_background(NULL); |
| 116 | 137 |
| 117 // Overrides border with AppListBubbleBorder. | 138 // Overrides border with AppListBubbleBorder. |
| 118 bubble_border_ = new AppListBubbleBorder(this); | 139 bubble_border_ = new AppListBubbleBorder(this, |
| 140 search_box_view_, |
| 141 apps_view_, |
| 142 search_results_view_); |
| 119 GetBubbleFrameView()->SetBubbleBorder(bubble_border_); | 143 GetBubbleFrameView()->SetBubbleBorder(bubble_border_); |
| 120 SizeToContents(); // Recalcuates with new border. | 144 SizeToContents(); // Recalcuates with new border. |
| 121 | 145 |
| 122 UpdateModel(); | 146 CreateModel(); |
| 123 } | 147 } |
| 124 | 148 |
| 125 void AppListView::AnimateShow(int duration_ms) { | 149 void AppListView::AnimateShow(int duration_ms) { |
| 126 if (bubble_style_) | 150 if (bubble_style_) |
| 127 return; | 151 return; |
| 128 | 152 |
| 129 ui::Layer* layer = model_view_->layer(); | 153 ui::Layer* layer = apps_view_->layer(); |
| 130 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | 154 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| 131 animation.SetTransitionDuration( | 155 animation.SetTransitionDuration( |
| 132 base::TimeDelta::FromMilliseconds(duration_ms)); | 156 base::TimeDelta::FromMilliseconds(duration_ms)); |
| 133 animation.SetTweenType(ui::Tween::EASE_OUT); | 157 animation.SetTweenType(ui::Tween::EASE_OUT); |
| 134 model_view_->SetTransform(ui::Transform()); | 158 apps_view_->SetTransform(ui::Transform()); |
| 135 } | 159 } |
| 136 | 160 |
| 137 void AppListView::AnimateHide(int duration_ms) { | 161 void AppListView::AnimateHide(int duration_ms) { |
| 138 if (bubble_style_) | 162 if (bubble_style_) |
| 139 return; | 163 return; |
| 140 | 164 |
| 141 ui::Layer* layer = model_view_->layer(); | 165 ui::Layer* layer = apps_view_->layer(); |
| 142 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); | 166 ui::ScopedLayerAnimationSettings animation(layer->GetAnimator()); |
| 143 animation.SetTransitionDuration( | 167 animation.SetTransitionDuration( |
| 144 base::TimeDelta::FromMilliseconds(duration_ms)); | 168 base::TimeDelta::FromMilliseconds(duration_ms)); |
| 145 animation.SetTweenType(ui::Tween::EASE_IN); | 169 animation.SetTweenType(ui::Tween::EASE_IN); |
| 146 model_view_->SetTransform(GetScaleTransform(model_view_)); | 170 apps_view_->SetTransform(GetScaleTransform(apps_view_)); |
| 147 } | 171 } |
| 148 | 172 |
| 149 void AppListView::Close() { | 173 void AppListView::Close() { |
| 150 if (delegate_.get()) | 174 if (delegate_.get()) |
| 151 delegate_->Close(); | 175 delegate_->Close(); |
| 152 else | 176 else |
| 153 GetWidget()->Close(); | 177 GetWidget()->Close(); |
| 154 } | 178 } |
| 155 | 179 |
| 156 void AppListView::UpdateBounds(const gfx::Rect& screen_bounds, | 180 void AppListView::UpdateBounds(const gfx::Rect& screen_bounds, |
| 157 const gfx::Rect& work_area) { | 181 const gfx::Rect& work_area) { |
| 158 if (bubble_style_) { | 182 if (bubble_style_) { |
| 159 SizeToContents(); | 183 SizeToContents(); |
| 160 } else { | 184 } else { |
| 161 work_area_ = work_area; | 185 work_area_ = work_area; |
| 162 GetWidget()->SetBounds(screen_bounds); | 186 GetWidget()->SetBounds(screen_bounds); |
| 163 } | 187 } |
| 164 } | 188 } |
| 165 | 189 |
| 166 void AppListView::UpdateModel() { | 190 void AppListView::CreateModel() { |
| 167 if (delegate_.get()) { | 191 if (delegate_.get()) { |
| 192 // Creates a new model and update all references before releasing old one. |
| 168 scoped_ptr<AppListModel> new_model(new AppListModel); | 193 scoped_ptr<AppListModel> new_model(new AppListModel); |
| 194 |
| 169 delegate_->SetModel(new_model.get()); | 195 delegate_->SetModel(new_model.get()); |
| 170 delegate_->UpdateModel(std::string()); | 196 apps_view_->SetModel(new_model->apps()); |
| 171 model_view_->SetModel(new_model.get()); | 197 |
| 198 // search_box_view_ etc are not created for v1. |
| 199 // TODO(xiyuan): Update this after v2 is ready. |
| 200 if (search_box_view_) |
| 201 search_box_view_->SetModel(new_model->search_box()); |
| 202 if (search_results_view_) |
| 203 search_results_view_->SetResults(new_model->results()); |
| 204 |
| 172 model_.reset(new_model.release()); | 205 model_.reset(new_model.release()); |
| 173 } | 206 } |
| 174 } | 207 } |
| 175 | 208 |
| 176 views::View* AppListView::GetInitiallyFocusedView() { | 209 views::View* AppListView::GetInitiallyFocusedView() { |
| 177 return model_view_; | 210 if (bubble_style_) |
| 211 return search_box_view_->search_box(); |
| 212 else |
| 213 return apps_view_; |
| 214 } |
| 215 |
| 216 gfx::Size AppListView::GetPreferredSize() { |
| 217 if (!bubble_style_) |
| 218 return View::GetPreferredSize(); |
| 219 |
| 220 const int search_box_height = search_box_view_->GetPreferredSize().height(); |
| 221 const int grid_height = apps_view_->GetPreferredSize().height(); |
| 222 const int page_switcher_height = |
| 223 page_switcher_view_->GetPreferredSize().height(); |
| 224 const int results_height = search_results_view_->GetPreferredSize().height(); |
| 225 |
| 226 int height = search_box_height + std::max(grid_height + page_switcher_height, |
| 227 results_height); |
| 228 return gfx::Size(kPreferredWidth, height); |
| 178 } | 229 } |
| 179 | 230 |
| 180 void AppListView::Layout() { | 231 void AppListView::Layout() { |
| 181 gfx::Rect rect(GetContentsBounds()); | 232 gfx::Rect rect(GetContentsBounds()); |
| 182 if (rect.IsEmpty()) | 233 if (rect.IsEmpty()) |
| 183 return; | 234 return; |
| 184 | 235 |
| 185 if (bubble_style_) { | 236 if (bubble_style_) { |
| 186 views::View::Layout(); | 237 rect.Inset(kInnerPadding, kInnerPadding); |
| 238 |
| 239 const int x = rect.x(); |
| 240 const int width = rect.width(); |
| 241 |
| 242 // SeachBoxView, AppsGridView and PageSwitcher uses a vertical box layout. |
| 243 int y = rect.y(); |
| 244 const int search_box_height = search_box_view_->GetPreferredSize().height(); |
| 245 gfx::Rect search_box_frame(gfx::Point(x, y), |
| 246 gfx::Size(width, search_box_height)); |
| 247 search_box_view_->SetBoundsRect(rect.Intersect(search_box_frame)); |
| 248 |
| 249 y = search_box_view_->bounds().bottom(); |
| 250 const int grid_height = apps_view_->GetPreferredSize().height(); |
| 251 gfx::Rect grid_frame(gfx::Point(x, y), gfx::Size(width, grid_height)); |
| 252 apps_view_->SetBoundsRect(rect.Intersect(grid_frame)); |
| 253 |
| 254 y = apps_view_->bounds().bottom(); |
| 255 const int page_switcher_height = rect.bottom() - y; |
| 256 gfx::Rect page_switcher_frame(gfx::Point(x, y), |
| 257 gfx::Size(width, page_switcher_height)); |
| 258 page_switcher_view_->SetBoundsRect(rect.Intersect(page_switcher_frame)); |
| 259 |
| 260 // Results view is mutually exclusive with AppsGridView and PageSwitcher. |
| 261 // It occupies the same space as those two views. |
| 262 gfx::Rect results_frame(grid_frame.Union(page_switcher_frame)); |
| 263 search_results_view_->SetBoundsRect(rect.Intersect(results_frame)); |
| 187 } else { | 264 } else { |
| 188 // Gets work area rect, which is in screen coordinates. | 265 // Gets work area rect, which is in screen coordinates. |
| 189 gfx::Rect workarea(work_area_); | 266 gfx::Rect workarea(work_area_); |
| 190 | 267 |
| 191 // Converts |workarea| into view's coordinates. | 268 // Converts |workarea| into view's coordinates. |
| 192 gfx::Point origin(workarea.origin()); | 269 gfx::Point origin(workarea.origin()); |
| 193 views::View::ConvertPointFromScreen(this, &origin); | 270 views::View::ConvertPointFromScreen(this, &origin); |
| 194 workarea.Offset(-origin.x(), -origin.y()); | 271 workarea.Offset(-origin.x(), -origin.y()); |
| 195 | 272 |
| 196 rect = rect.Intersect(workarea); | 273 rect = rect.Intersect(workarea); |
| 197 model_view_->SetBoundsRect(rect); | 274 apps_view_->SetBoundsRect(rect); |
| 198 } | 275 } |
| 199 } | 276 } |
| 200 | 277 |
| 201 bool AppListView::OnKeyPressed(const views::KeyEvent& event) { | 278 bool AppListView::OnKeyPressed(const views::KeyEvent& event) { |
| 202 if (event.key_code() == ui::VKEY_ESCAPE) { | 279 if (event.key_code() == ui::VKEY_ESCAPE) { |
| 203 Close(); | 280 Close(); |
| 204 return true; | 281 return true; |
| 205 } | 282 } |
| 206 | 283 |
| 207 return false; | 284 return false; |
| 208 } | 285 } |
| 209 | 286 |
| 210 bool AppListView::OnMousePressed(const views::MouseEvent& event) { | 287 bool AppListView::OnMousePressed(const views::MouseEvent& event) { |
| 211 // For full screen mode, if mouse click reaches us, this means user clicks | 288 // For full screen mode, if mouse click reaches us, this means user clicks |
| 212 // on blank area. So close. | 289 // on blank area. So close. |
| 213 if (!bubble_style_) | 290 if (!bubble_style_) |
| 214 Close(); | 291 Close(); |
| 215 | 292 |
| 216 return true; | 293 return true; |
| 217 } | 294 } |
| 218 | 295 |
| 219 void AppListView::ButtonPressed(views::Button* sender, | 296 void AppListView::ButtonPressed(views::Button* sender, |
| 220 const views::Event& event) { | 297 const views::Event& event) { |
| 221 if (sender->GetClassName() != AppListItemView::kViewClassName) | 298 if (sender->GetClassName() != AppListItemView::kViewClassName) |
| 222 return; | 299 return; |
| 223 | 300 |
| 224 if (delegate_.get()) { | 301 if (delegate_.get()) { |
| 225 delegate_->OnAppListItemActivated( | 302 delegate_->ActivateAppListItem( |
| 226 static_cast<AppListItemView*>(sender)->model(), | 303 static_cast<AppListItemView*>(sender)->model(), |
| 227 event.flags()); | 304 event.flags()); |
| 228 } | 305 } |
| 229 Close(); | 306 Close(); |
| 230 } | 307 } |
| 231 | 308 |
| 232 gfx::Rect AppListView::GetBubbleBounds() { | 309 gfx::Rect AppListView::GetBubbleBounds() { |
| 233 // This happens before replacing the default border. | 310 // This happens before replacing the default border. |
| 234 if (!bubble_border_) | 311 if (!bubble_border_) |
| 235 return views::BubbleDelegateView::GetBubbleBounds(); | 312 return views::BubbleDelegateView::GetBubbleBounds(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 261 // it points to the same position before the move. | 338 // it points to the same position before the move. |
| 262 bubble_border_->set_arrow_offset(-offset); | 339 bubble_border_->set_arrow_offset(-offset); |
| 263 | 340 |
| 264 // Repaints border if arrow offset is changed. | 341 // Repaints border if arrow offset is changed. |
| 265 if (bubble_border_->arrow_offset() != old_arrow_offset) | 342 if (bubble_border_->arrow_offset() != old_arrow_offset) |
| 266 GetBubbleFrameView()->SchedulePaint(); | 343 GetBubbleFrameView()->SchedulePaint(); |
| 267 | 344 |
| 268 return bubble_rect; | 345 return bubble_rect; |
| 269 } | 346 } |
| 270 | 347 |
| 348 void AppListView::QueryChanged(SearchBoxView* sender) { |
| 349 bool showing_search = search_results_view_->visible(); |
| 350 bool should_show_search = !model_->search_box()->text().empty(); |
| 351 |
| 352 if (delegate_.get()) { |
| 353 if (should_show_search) |
| 354 delegate_->StartSearch(); |
| 355 else |
| 356 delegate_->StopSearch(); |
| 357 } |
| 358 |
| 359 if (showing_search != should_show_search) { |
| 360 // TODO(xiyuan): Animate this transition. |
| 361 apps_view_->SetVisible(!should_show_search); |
| 362 page_switcher_view_->SetVisible(!should_show_search); |
| 363 search_results_view_->SetVisible(should_show_search); |
| 364 |
| 365 // TODO(xiyuan): Highlight default match instead of the first. |
| 366 if (search_results_view_->visible()) |
| 367 search_results_view_->SetSelectedIndex(0); |
| 368 |
| 369 // Needs to repaint frame as well. |
| 370 GetBubbleFrameView()->SchedulePaint(); |
| 371 } |
| 372 } |
| 373 |
| 374 void AppListView::OpenResult(const SearchResult& result, int event_flags) { |
| 375 if (delegate_.get()) |
| 376 delegate_->OpenSearchResult(result, event_flags); |
| 377 Close(); |
| 378 } |
| 379 |
| 271 } // namespace app_list | 380 } // namespace app_list |
| OLD | NEW |