| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h" | 5 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #import "base/mac/foundation_util.h" |
| 8 #import "base/mac/scoped_nsobject.h" | 9 #import "base/mac/scoped_nsobject.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 10 #import "ios/chrome/browser/tabs/tab.h" | 11 #import "ios/chrome/browser/tabs/tab.h" |
| 11 #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" | 12 #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" |
| 12 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h" | 13 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h" |
| 13 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h" | 14 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h" |
| 14 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.h" | 15 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.h" |
| 15 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h" | 16 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h" |
| 16 #include "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h" | 17 #include "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h" |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 void FillVectorWithHashesUsingDistantSession( | 21 void FillVectorWithHashesUsingDistantSession( |
| 21 synced_sessions::DistantSession const& session, | 22 synced_sessions::DistantSession const& session, |
| 22 std::vector<size_t>* hashes) { | 23 std::vector<size_t>* hashes) { |
| 23 DCHECK(hashes); | 24 DCHECK(hashes); |
| 24 DCHECK(hashes->empty()); | 25 DCHECK(hashes->empty()); |
| 25 for (size_t i = 0; i < session.tabs.size(); ++i) { | 26 for (size_t i = 0; i < session.tabs.size(); ++i) { |
| 26 hashes->push_back(session.tabs[i]->hashOfUserVisibleProperties()); | 27 hashes->push_back(session.tabs[i]->hashOfUserVisibleProperties()); |
| 27 } | 28 } |
| 28 } | 29 } |
| 29 | 30 |
| 30 } // namespace | 31 } // namespace |
| 31 | 32 |
| 32 @interface TabSwitcherPanelController ()<UICollectionViewDataSource, | 33 @interface TabSwitcherPanelController ()<UICollectionViewDataSource, |
| 34 UICollectionViewDelegate, |
| 33 SessionCellDelegate> { | 35 SessionCellDelegate> { |
| 34 ios::ChromeBrowserState* _browserState; // Weak. | 36 ios::ChromeBrowserState* _browserState; // Weak. |
| 35 base::scoped_nsobject<TabSwitcherPanelView> _panelView; | 37 base::scoped_nsobject<TabSwitcherPanelView> _panelView; |
| 36 base::scoped_nsobject<TabSwitcherModel> _model; | 38 base::scoped_nsobject<TabSwitcherModel> _model; |
| 37 std::string _sessionTag; | 39 std::string _sessionTag; |
| 38 TabSwitcherSessionType _sessionType; | 40 TabSwitcherSessionType _sessionType; |
| 39 base::scoped_nsobject<TabSwitcherCache> _cache; | 41 base::scoped_nsobject<TabSwitcherCache> _cache; |
| 40 base::scoped_nsobject<TabSwitcherPanelOverlayView> _overlayView; | 42 base::scoped_nsobject<TabSwitcherPanelOverlayView> _overlayView; |
| 41 std::unique_ptr<const synced_sessions::DistantSession> _distantSession; | 43 std::unique_ptr<const synced_sessions::DistantSession> _distantSession; |
| 42 std::unique_ptr<const TabModelSnapshot> _localSession; | 44 std::unique_ptr<const TabModelSnapshot> _localSession; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 } else { | 210 } else { |
| 209 CHECK(_localSession); | 211 CHECK(_localSession); |
| 210 NSInteger numberOfTabs = _localSession->tabs().size(); | 212 NSInteger numberOfTabs = _localSession->tabs().size(); |
| 211 [self setZeroTabStateOverlayVisible:numberOfTabs == 0]; | 213 [self setZeroTabStateOverlayVisible:numberOfTabs == 0]; |
| 212 return numberOfTabs; | 214 return numberOfTabs; |
| 213 } | 215 } |
| 214 } | 216 } |
| 215 | 217 |
| 216 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView | 218 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView |
| 217 cellForItemAtIndexPath:(NSIndexPath*)indexPath { | 219 cellForItemAtIndexPath:(NSIndexPath*)indexPath { |
| 218 UICollectionViewCell* cell = nil; | 220 TabSwitcherSessionCell* cell = nil; |
| 219 NSUInteger tabIndex = indexPath.item; | 221 NSUInteger tabIndex = indexPath.item; |
| 220 if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { | 222 if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { |
| 221 cell = [collectionView | 223 NSString* identifier = [TabSwitcherDistantSessionCell identifier]; |
| 222 dequeueReusableCellWithReuseIdentifier:[TabSwitcherDistantSessionCell | |
| 223 identifier] | |
| 224 forIndexPath:indexPath]; | |
| 225 DCHECK([cell isKindOfClass:[TabSwitcherDistantSessionCell class]]); | |
| 226 TabSwitcherDistantSessionCell* panelCell = | 224 TabSwitcherDistantSessionCell* panelCell = |
| 227 static_cast<TabSwitcherDistantSessionCell*>(cell); | 225 base::mac::ObjCCastStrict<TabSwitcherDistantSessionCell>([collectionView |
| 226 dequeueReusableCellWithReuseIdentifier:identifier |
| 227 forIndexPath:indexPath]); |
| 228 cell = panelCell; |
| 229 |
| 228 CHECK(_distantSession); | 230 CHECK(_distantSession); |
| 229 const std::size_t distantSessionTabCount = _distantSession->tabs.size(); | 231 const std::size_t distantSessionTabCount = _distantSession->tabs.size(); |
| 230 LOG_ASSERT(tabIndex < distantSessionTabCount) | 232 LOG_ASSERT(tabIndex < distantSessionTabCount) |
| 231 << "tabIndex == " << tabIndex | 233 << "tabIndex == " << tabIndex |
| 232 << " _distantSession->tabs.size() == " << distantSessionTabCount; | 234 << " _distantSession->tabs.size() == " << distantSessionTabCount; |
| 233 synced_sessions::DistantTab* tab = _distantSession->tabs[tabIndex].get(); | 235 synced_sessions::DistantTab* tab = _distantSession->tabs[tabIndex].get(); |
| 234 CHECK(tab); | 236 CHECK(tab); |
| 235 [panelCell setTitle:SysUTF16ToNSString(tab->title)]; | 237 [panelCell setTitle:SysUTF16ToNSString(tab->title)]; |
| 236 [panelCell setSessionGURL:tab->virtual_url | 238 [panelCell setSessionGURL:tab->virtual_url |
| 237 withBrowserState:[_model browserState]]; | 239 withBrowserState:[_model browserState]]; |
| 238 [panelCell setDelegate:self]; | |
| 239 } else { | 240 } else { |
| 240 cell = [collectionView | 241 NSString* identifier = [TabSwitcherLocalSessionCell identifier]; |
| 241 dequeueReusableCellWithReuseIdentifier:[TabSwitcherLocalSessionCell | |
| 242 identifier] | |
| 243 forIndexPath:indexPath]; | |
| 244 DCHECK([cell isKindOfClass:[TabSwitcherLocalSessionCell class]]); | |
| 245 TabSwitcherLocalSessionCell* panelCell = | 242 TabSwitcherLocalSessionCell* panelCell = |
| 246 static_cast<TabSwitcherLocalSessionCell*>(cell); | 243 base::mac::ObjCCastStrict<TabSwitcherLocalSessionCell>([collectionView |
| 244 dequeueReusableCellWithReuseIdentifier:identifier |
| 245 forIndexPath:indexPath]); |
| 246 cell = panelCell; |
| 247 |
| 247 Tab* tab = _localSession->tabs()[tabIndex]; | 248 Tab* tab = _localSession->tabs()[tabIndex]; |
| 248 [panelCell setDelegate:self]; | |
| 249 [panelCell setSessionType:_sessionType]; | 249 [panelCell setSessionType:_sessionType]; |
| 250 [panelCell setAppearanceForTab:tab cellSize:[_panelView cellSize]]; | 250 [panelCell setAppearanceForTab:tab cellSize:[_panelView cellSize]]; |
| 251 } | 251 } |
| 252 DCHECK(cell); |
| 253 cell.delegate = self; |
| 252 return cell; | 254 return cell; |
| 253 } | 255 } |
| 254 | 256 |
| 257 - (void)collectionView:(UICollectionView*)collectionView |
| 258 didEndDisplayingCell:(UICollectionViewCell*)cell |
| 259 forItemAtIndexPath:(NSIndexPath*)indexPath { |
| 260 // When closing the last tab, accessibility does not realize that there is no |
| 261 // elements in the collection view and keep the custom action for the tab. So |
| 262 // reset the delegate of the cell (to avoid crashing if the action is invoked) |
| 263 // and post a notification that the screen changed to force accessibility to |
| 264 // re-inspect the whole screen. See http://crbug.com/677374 for crash log. |
| 265 base::mac::ObjCCastStrict<TabSwitcherSessionCell>(cell).delegate = nil; |
| 266 UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, |
| 267 nil); |
| 268 } |
| 269 |
| 255 #pragma mark - SessionCellDelegate | 270 #pragma mark - SessionCellDelegate |
| 256 | 271 |
| 257 - (TabSwitcherCache*)tabSwitcherCache { | 272 - (TabSwitcherCache*)tabSwitcherCache { |
| 258 return _cache; | 273 return _cache; |
| 259 } | 274 } |
| 260 | 275 |
| 261 - (void)cellPressed:(UICollectionViewCell*)cell { | 276 - (void)cellPressed:(UICollectionViewCell*)cell { |
| 262 const NSInteger tabIndex = | 277 const NSInteger tabIndex = |
| 263 [[_panelView collectionView] indexPathForCell:cell].item; | 278 [[_panelView collectionView] indexPathForCell:cell].item; |
| 264 | 279 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 [self.delegate | 334 [self.delegate |
| 320 tabSwitcherPanelControllerDidUpdateOverlayViewVisibility: | 335 tabSwitcherPanelControllerDidUpdateOverlayViewVisibility: |
| 321 self]; | 336 self]; |
| 322 }]; | 337 }]; |
| 323 } | 338 } |
| 324 | 339 |
| 325 - (void)loadView { | 340 - (void)loadView { |
| 326 _panelView.reset( | 341 _panelView.reset( |
| 327 [[TabSwitcherPanelView alloc] initWithSessionType:_sessionType]); | 342 [[TabSwitcherPanelView alloc] initWithSessionType:_sessionType]); |
| 328 _panelView.get().collectionView.dataSource = self; | 343 _panelView.get().collectionView.dataSource = self; |
| 344 _panelView.get().collectionView.delegate = self; |
| 329 } | 345 } |
| 330 | 346 |
| 331 - (synced_sessions::DistantSession const*)distantSession { | 347 - (synced_sessions::DistantSession const*)distantSession { |
| 332 return _distantSession.get(); | 348 return _distantSession.get(); |
| 333 } | 349 } |
| 334 | 350 |
| 335 @end | 351 @end |
| OLD | NEW |