apps_grid_view.h revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 3// found in the LICENSE file. 4 5#ifndef UI_APP_LIST_VIEWS_APPS_GRID_VIEW_H_ 6#define UI_APP_LIST_VIEWS_APPS_GRID_VIEW_H_ 7 8#include "base/basictypes.h" 9#include "base/compiler_specific.h" 10#include "base/timer/timer.h" 11#include "ui/app_list/app_list_export.h" 12#include "ui/app_list/app_list_model.h" 13#include "ui/app_list/app_list_model_observer.h" 14#include "ui/app_list/pagination_model_observer.h" 15#include "ui/base/models/list_model_observer.h" 16#include "ui/views/animation/bounds_animator.h" 17#include "ui/views/controls/button/button.h" 18#include "ui/views/view.h" 19#include "ui/views/view_model.h" 20 21#if defined(OS_WIN) && !defined(USE_AURA) 22#include "ui/base/dragdrop/drag_source_win.h" 23#endif 24 25namespace views { 26class ButtonListener; 27class DragImageView; 28} 29 30namespace app_list { 31 32#if defined(OS_WIN) && !defined(USE_AURA) 33class SynchronousDrag; 34#endif 35 36namespace test { 37class AppsGridViewTestApi; 38} 39 40class ApplicationDragAndDropHost; 41class AppListItemView; 42class AppsGridViewDelegate; 43class PageSwitcher; 44class PaginationModel; 45 46// AppsGridView displays a grid for AppListModel::Apps sub model. 47class APP_LIST_EXPORT AppsGridView : public views::View, 48 public views::ButtonListener, 49 public ui::ListModelObserver, 50 public PaginationModelObserver, 51 public AppListModelObserver { 52 public: 53 enum Pointer { 54 NONE, 55 MOUSE, 56 TOUCH, 57 }; 58 59 AppsGridView(AppsGridViewDelegate* delegate, 60 PaginationModel* pagination_model); 61 virtual ~AppsGridView(); 62 63 // Sets fixed layout parameters. After setting this, CalculateLayout below 64 // is no longer called to dynamically choosing those layout params. 65 void SetLayout(int icon_size, int cols, int rows_per_page); 66 67 // Sets |model| to use. Note this does not take ownership of |model|. 68 void SetModel(AppListModel* model); 69 70 void SetSelectedView(views::View* view); 71 void ClearSelectedView(views::View* view); 72 bool IsSelectedView(const views::View* view) const; 73 74 // Ensures the view is visible. Note that if there is a running page 75 // transition, this does nothing. 76 void EnsureViewVisible(const views::View* view); 77 78 void InitiateDrag(AppListItemView* view, 79 Pointer pointer, 80 const ui::LocatedEvent& event); 81 82 // Called from AppListItemView when it receives a drag event. 83 void UpdateDragFromItem(Pointer pointer, 84 const ui::LocatedEvent& event); 85 86 // Called when the user is dragging an app. |point| is in grid view 87 // coordinates. 88 void UpdateDrag(Pointer pointer, const gfx::Point& point); 89 void EndDrag(bool cancel); 90 bool IsDraggedView(const views::View* view) const; 91 92 void StartSettingUpSynchronousDrag(); 93 bool RunSynchronousDrag(); 94 void CleanUpSynchronousDrag(); 95 void OnGotShortcutPath(const base::FilePath& path); 96 97 // Set the drag and drop host for application links. 98 void SetDragAndDropHostOfCurrentAppList( 99 ApplicationDragAndDropHost* drag_and_drop_host); 100 101 // Prerenders the icons on and around |page_index|. 102 void Prerender(int page_index); 103 104 bool has_dragged_view() const { return drag_view_ != NULL; } 105 bool dragging() const { return drag_pointer_ != NONE; } 106 107 // Overridden from views::View: 108 virtual gfx::Size GetPreferredSize() OVERRIDE; 109 virtual void Layout() OVERRIDE; 110 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 111 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE; 112 virtual void ViewHierarchyChanged( 113 const ViewHierarchyChangedDetails& details) OVERRIDE; 114 virtual bool GetDropFormats( 115 int* formats, 116 std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE; 117 virtual bool CanDrop(const OSExchangeData& data) OVERRIDE; 118 virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE; 119 120 // Stops the timer that triggers a page flip during a drag. 121 void StopPageFlipTimer(); 122 123 // Get the last grid view which was created. 124 static AppsGridView* GetLastGridViewForTest(); 125 126 // Return the view model for test purposes. 127 const views::ViewModel* view_model_for_test() const { return &view_model_; } 128 129 // For test: Return if the drag and drop handler was set. 130 bool has_drag_and_drop_host_for_test() { return NULL != drag_and_drop_host_; } 131 132 // For test: Return if the drag and drop operation gets dispatched. 133 bool forward_events_to_drag_and_drop_host_for_test() { 134 return forward_events_to_drag_and_drop_host_; 135 } 136 137 private: 138 friend class app_list::test::AppsGridViewTestApi; 139 140 // Represents the index to an item view in the grid. 141 struct Index { 142 Index() : page(-1), slot(-1) {} 143 Index(int page, int slot) : page(page), slot(slot) {} 144 145 bool operator==(const Index& other) const { 146 return page == other.page && slot == other.slot; 147 } 148 bool operator!=(const Index& other) const { 149 return page != other.page || slot != other.slot; 150 } 151 152 int page; // Which page an item view is on. 153 int slot; // Which slot in the page an item view is in. 154 }; 155 156 int tiles_per_page() const { return cols_ * rows_per_page_; } 157 158 // Updates from model. 159 void Update(); 160 161 // Updates page splits for item views. 162 void UpdatePaging(); 163 164 // Updates the number of pulsing block views based on AppListModel status and 165 // number of apps. 166 void UpdatePulsingBlockViews(); 167 168 views::View* CreateViewForItemAtIndex(size_t index); 169 170 void SetSelectedItemByIndex(const Index& index); 171 bool IsValidIndex(const Index& index) const; 172 173 Index GetIndexOfView(const views::View* view) const; 174 views::View* GetViewAtIndex(const Index& index) const; 175 176 void MoveSelected(int page_delta, int slot_x_delta, int slot_y_delta); 177 178 void CalculateIdealBounds(); 179 void AnimateToIdealBounds(); 180 181 // Invoked when the given |view|'s current bounds and target bounds are on 182 // different rows. To avoid moving diagonally, |view| would be put into a 183 // slot prior |target| and fade in while moving to |target|. In the meanwhile, 184 // a layer copy of |view| would start at |current| and fade out while moving 185 // to succeeding slot of |current|. |animate_current| controls whether to run 186 // fading out animation from |current|. |animate_target| controls whether to 187 // run fading in animation to |target|. 188 void AnimationBetweenRows(views::View* view, 189 bool animate_current, 190 const gfx::Rect& current, 191 bool animate_target, 192 const gfx::Rect& target); 193 194 // Extracts drag location info from |event| into |drag_point|. 195 void ExtractDragLocation(const ui::LocatedEvent& event, 196 gfx::Point* drag_point); 197 198 // Calculates |drop_target_| based on |drag_point|. |drag_point| is in the 199 // grid view's coordinates. When |use_page_button_hovering| is true and 200 // |drag_point| is hovering on a page button, use the last slot on that page 201 // as drop target. 202 void CalculateDropTarget(const gfx::Point& drag_point, 203 bool use_page_button_hovering); 204 205 // Prepares |drag_and_drop_host_| for dragging. |grid_location| contains 206 // the drag point in this grid view's coordinates. 207 void StartDragAndDropHostDrag(const gfx::Point& grid_location); 208 209 // Dispatch the drag and drop update event to the dnd host (if needed). 210 void DispatchDragEventToDragAndDropHost(const gfx::Point& point); 211 212 // Starts the page flip timer if |drag_point| is in left/right side page flip 213 // zone or is over page switcher. 214 void MaybeStartPageFlipTimer(const gfx::Point& drag_point); 215 216 // Invoked when |page_flip_timer_| fires. 217 void OnPageFlipTimer(); 218 219 // Updates |model_| to move item represented by |item_view| to |target| slot. 220 void MoveItemInModel(views::View* item_view, const Index& target); 221 222 // Cancels any context menus showing for app items on the current page. 223 void CancelContextMenusOnCurrentPage(); 224 225 // Overridden from views::ButtonListener: 226 virtual void ButtonPressed(views::Button* sender, 227 const ui::Event& event) OVERRIDE; 228 229 // Overridden from ListModelObserver: 230 virtual void ListItemsAdded(size_t start, size_t count) OVERRIDE; 231 virtual void ListItemsRemoved(size_t start, size_t count) OVERRIDE; 232 virtual void ListItemMoved(size_t index, size_t target_index) OVERRIDE; 233 virtual void ListItemsChanged(size_t start, size_t count) OVERRIDE; 234 235 // Overridden from PaginationModelObserver: 236 virtual void TotalPagesChanged() OVERRIDE; 237 virtual void SelectedPageChanged(int old_selected, int new_selected) OVERRIDE; 238 virtual void TransitionStarted() OVERRIDE; 239 virtual void TransitionChanged() OVERRIDE; 240 241 // Overridden from AppListModelObserver: 242 virtual void OnAppListModelStatusChanged() OVERRIDE; 243 244 // Hide a given view temporarily without losing (mouse) events and / or 245 // changing the size of it. 246 void HideView(views::View* view, bool hide); 247 248 AppListModel* model_; // Owned by AppListView. 249 AppsGridViewDelegate* delegate_; 250 PaginationModel* pagination_model_; // Owned by AppListController. 251 PageSwitcher* page_switcher_view_; // Owned by views hierarchy. 252 253 gfx::Size icon_size_; 254 int cols_; 255 int rows_per_page_; 256 257 // Tracks app item views. There is a view per item in |model_|. 258 views::ViewModel view_model_; 259 260 // Tracks pulsing block views. 261 views::ViewModel pulsing_blocks_model_; 262 263 views::View* selected_view_; 264 265 AppListItemView* drag_view_; 266 267 // The point where the drag started in AppListItemView coordinates. 268 gfx::Point drag_view_offset_; 269 270 // The point where the drag started in GridView coordinates. 271 gfx::Point drag_start_grid_view_; 272 273 // The location of |drag_view_| when the drag started. 274 gfx::Point drag_view_start_; 275 276#if defined(OS_WIN) && !defined(USE_AURA) 277 // Created when a drag is started (ie: drag exceeds the drag threshold), but 278 // not Run() until supplied with a shortcut path. 279 scoped_refptr<SynchronousDrag> synchronous_drag_; 280#endif 281 282 Pointer drag_pointer_; 283 Index drop_target_; 284 285 // An application target drag and drop host which accepts dnd operations. 286 ApplicationDragAndDropHost* drag_and_drop_host_; 287 288 // The drag operation is currently inside the dnd host and events get 289 // forwarded. 290 bool forward_events_to_drag_and_drop_host_; 291 292 // Last mouse drag location in this view's coordinates. 293 gfx::Point last_drag_point_; 294 295 // Timer to auto flip page when dragging an item near the left/right edges. 296 base::OneShotTimer<AppsGridView> page_flip_timer_; 297 298 // Target page to switch to when |page_flip_timer_| fires. 299 int page_flip_target_; 300 301 // Delay in milliseconds of when |page_flip_timer_| should fire after user 302 // drags an item near the edges. 303 int page_flip_delay_in_ms_; 304 305 views::BoundsAnimator bounds_animator_; 306 307 DISALLOW_COPY_AND_ASSIGN(AppsGridView); 308}; 309 310} // namespace app_list 311 312#endif // UI_APP_LIST_VIEWS_APPS_GRID_VIEW_H_ 313