| OLD | NEW | 
|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 #import "ios/chrome/browser/ui/stack_view/card_stack_layout_manager.h" | 5 #import "ios/chrome/browser/ui/stack_view/card_stack_layout_manager.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <cmath> | 8 #include <cmath> | 
| 9 | 9 | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| 11 #include "ios/chrome/browser/ui/rtl_geometry.h" | 11 #include "ios/chrome/browser/ui/rtl_geometry.h" | 
|  | 12 #import "ios/chrome/browser/ui/stack_view/card_view.h" | 
| 12 #import "ios/chrome/browser/ui/stack_view/stack_card.h" | 13 #import "ios/chrome/browser/ui/stack_view/stack_card.h" | 
|  | 14 #import "ios/chrome/browser/ui/stack_view/title_label.h" | 
| 13 #import "ios/chrome/browser/ui/ui_util.h" | 15 #import "ios/chrome/browser/ui/ui_util.h" | 
| 14 | 16 | 
|  | 17 #if !defined(__has_feature) || !__has_feature(objc_arc) | 
|  | 18 #error "This file requires ARC support." | 
|  | 19 #endif | 
|  | 20 | 
| 15 namespace { | 21 namespace { | 
| 16 | 22 | 
| 17 // The maximum number of cards that should be staggered at a collapse point. | 23 // The maximum number of cards that should be staggered at a collapse point. | 
| 18 const NSInteger kMaxVisibleStaggerCount = 4; | 24 const NSInteger kMaxVisibleStaggerCount = 4; | 
| 19 // The amount that each of the staggered cards in a stack should be staggered | 25 // The amount that each of the staggered cards in a stack should be staggered | 
| 20 // when fully collapsed. | 26 // when fully collapsed. | 
| 21 const CGFloat kMinStackStaggerAmount = 4.0; | 27 const CGFloat kMinStackStaggerAmount = 4.0; | 
| 22 // The amount that a card should overlap with a previous/subsequent card when | 28 // The amount that a card should overlap with a previous/subsequent card when | 
| 23 // it is extended the maximum distance away (e.g., after a multitouch event). | 29 // it is extended the maximum distance away (e.g., after a multitouch event). | 
| 24 const CGFloat kFullyExtendedCardOverlap = 8.0; | 30 const CGFloat kFullyExtendedCardOverlap = 8.0; | 
| 25 // The amount that a card's position is allowed to drift toward overextension | 31 // The amount that a card's position is allowed to drift toward overextension | 
| 26 // before the card is considered to be overextended (i.e., an epsilon to allow | 32 // before the card is considered to be overextended (i.e., an epsilon to allow | 
| 27 // for floating-point imprecision). | 33 // for floating-point imprecision). | 
| 28 const CGFloat kDistanceBeforeOverextension = 0.0001; | 34 const CGFloat kDistanceBeforeOverextension = 0.0001; | 
| 29 // The factor by which scroll is decayed on overscroll. | 35 // The factor by which scroll is decayed on overscroll. | 
| 30 const CGFloat kOverextensionDecayFactor = 2.0; | 36 const CGFloat kOverextensionDecayFactor = 2.0; | 
| 31 // The amount by which a card is scrolled when asked to scroll it away from its | 37 // The amount by which a card is scrolled when asked to scroll it away from its | 
| 32 // preceding neighbor. | 38 // preceding neighbor. | 
| 33 const CGFloat kScrollAwayFromNeighborAmount = 200; | 39 const CGFloat kScrollAwayFromNeighborAmount = 200; | 
| 34 | 40 | 
| 35 }  // namespace | 41 }  // namespace | 
| 36 | 42 | 
| 37 @interface CardStackLayoutManager () | 43 @interface CardStackLayoutManager () { | 
|  | 44   NSMutableArray* cards_; | 
|  | 45   // YES if the previous call to one of {|scrollCardAtIndex|, | 
|  | 46   // |handleMultitouchWithFirstDelta|} was to the former method; NO otherwise. | 
|  | 47   BOOL treatOverExtensionAsScroll_; | 
|  | 48   NSUInteger previousFirstPinchCardIndex_; | 
|  | 49   NSUInteger previousSecondPinchCardIndex_; | 
|  | 50 } | 
| 38 | 51 | 
| 39 // Exposes |kMinStackStaggerAmount| for tests. | 52 // Exposes |kMinStackStaggerAmount| for tests. | 
| 40 - (CGFloat)minStackStaggerAmount; | 53 - (CGFloat)minStackStaggerAmount; | 
| 41 // Exposes |kScrollAwayFromNeighborAmount| for tests. | 54 // Exposes |kScrollAwayFromNeighborAmount| for tests. | 
| 42 - (CGFloat)scrollCardAwayFromNeighborAmount; | 55 - (CGFloat)scrollCardAwayFromNeighborAmount; | 
| 43 // Returns the current start stack limit allowing for overextension as follows: | 56 // Returns the current start stack limit allowing for overextension as follows: | 
| 44 // - If the card at |index| is not overextended toward the start, returns | 57 // - If the card at |index| is not overextended toward the start, returns | 
| 45 // |startLimit_|. | 58 // |startLimit_|. | 
| 46 // - Otherwise, returns the value of the start limit such that the position of | 59 // - Otherwise, returns the value of the start limit such that the position of | 
| 47 // the card at |index| in the start stack is its current position (with the | 60 // the card at |index| in the start stack is its current position (with the | 
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 187 @synthesize maximumOverextensionAmount = maximumOverextensionAmount_; | 200 @synthesize maximumOverextensionAmount = maximumOverextensionAmount_; | 
| 188 @synthesize endLimit = endLimit_; | 201 @synthesize endLimit = endLimit_; | 
| 189 @synthesize layoutAxisPosition = layoutAxisPosition_; | 202 @synthesize layoutAxisPosition = layoutAxisPosition_; | 
| 190 @synthesize startLimit = startLimit_; | 203 @synthesize startLimit = startLimit_; | 
| 191 @synthesize layoutIsVertical = layoutIsVertical_; | 204 @synthesize layoutIsVertical = layoutIsVertical_; | 
| 192 @synthesize lastStartStackCardIndex = lastStartStackCardIndex_; | 205 @synthesize lastStartStackCardIndex = lastStartStackCardIndex_; | 
| 193 @synthesize firstEndStackCardIndex = firstEndStackCardIndex_; | 206 @synthesize firstEndStackCardIndex = firstEndStackCardIndex_; | 
| 194 | 207 | 
| 195 - (id)init { | 208 - (id)init { | 
| 196   if ((self = [super init])) { | 209   if ((self = [super init])) { | 
| 197     cards_.reset([[NSMutableArray alloc] init]); | 210     cards_ = [[NSMutableArray alloc] init]; | 
| 198     layoutIsVertical_ = YES; | 211     layoutIsVertical_ = YES; | 
| 199     lastStartStackCardIndex_ = -1; | 212     lastStartStackCardIndex_ = -1; | 
| 200     firstEndStackCardIndex_ = -1; | 213     firstEndStackCardIndex_ = -1; | 
| 201   } | 214   } | 
| 202   return self; | 215   return self; | 
| 203 } | 216 } | 
| 204 | 217 | 
| 205 - (CGFloat)minStackStaggerAmount { | 218 - (CGFloat)minStackStaggerAmount { | 
| 206   return kMinStackStaggerAmount; | 219   return kMinStackStaggerAmount; | 
| 207 } | 220 } | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 240   lastStartStackCardIndex_ = -1; | 253   lastStartStackCardIndex_ = -1; | 
| 241   firstEndStackCardIndex_ = -1; | 254   firstEndStackCardIndex_ = -1; | 
| 242   [cards_ removeAllObjects]; | 255   [cards_ removeAllObjects]; | 
| 243 } | 256 } | 
| 244 | 257 | 
| 245 - (void)setCardSize:(CGSize)size { | 258 - (void)setCardSize:(CGSize)size { | 
| 246   cardSize_ = size; | 259   cardSize_ = size; | 
| 247   NSUInteger i = 0; | 260   NSUInteger i = 0; | 
| 248   CGFloat previousFirstCardOffset = 0; | 261   CGFloat previousFirstCardOffset = 0; | 
| 249   CGFloat newFirstCardOffset = 0; | 262   CGFloat newFirstCardOffset = 0; | 
| 250   for (StackCard* card in cards_.get()) { | 263   for (StackCard* card in cards_) { | 
| 251     CGFloat offset = [self cardOffsetOnLayoutAxis:card]; | 264     CGFloat offset = [self cardOffsetOnLayoutAxis:card]; | 
| 252     card.size = cardSize_; | 265     card.size = cardSize_; | 
| 253     CGFloat newOffset = offset; | 266     CGFloat newOffset = offset; | 
| 254 | 267 | 
| 255     // Attempt to preserve card positions, but ensure that the deck starts | 268     // Attempt to preserve card positions, but ensure that the deck starts | 
| 256     // within overextension limits and that all cards not in the start stack are | 269     // within overextension limits and that all cards not in the start stack are | 
| 257     // within minimum/maximum separation limits of their preceding neighbors. | 270     // within minimum/maximum separation limits of their preceding neighbors. | 
| 258     if (i == 0) { | 271     if (i == 0) { | 
| 259       newOffset = std::max(newOffset, [self limitOfOverextensionTowardStart]); | 272       newOffset = std::max(newOffset, [self limitOfOverextensionTowardStart]); | 
| 260       newOffset = std::min(newOffset, [self limitOfOverscrollTowardEnd]); | 273       newOffset = std::min(newOffset, [self limitOfOverscrollTowardEnd]); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 282   for (NSUInteger i = 0; i < [cards_ count]; i++) { | 295   for (NSUInteger i = 0; i < [cards_ count]; i++) { | 
| 283     LayoutRectPosition position = [[cards_ objectAtIndex:i] layout].position; | 296     LayoutRectPosition position = [[cards_ objectAtIndex:i] layout].position; | 
| 284     CGFloat prevLayoutAxisOffset = | 297     CGFloat prevLayoutAxisOffset = | 
| 285         layoutIsVertical_ ? position.leading : position.originY; | 298         layoutIsVertical_ ? position.leading : position.originY; | 
| 286     [self moveOriginOfCardAtIndex:i toOffset:prevLayoutAxisOffset]; | 299     [self moveOriginOfCardAtIndex:i toOffset:prevLayoutAxisOffset]; | 
| 287   } | 300   } | 
| 288 } | 301 } | 
| 289 | 302 | 
| 290 - (void)setLayoutAxisPosition:(CGFloat)position { | 303 - (void)setLayoutAxisPosition:(CGFloat)position { | 
| 291   layoutAxisPosition_ = position; | 304   layoutAxisPosition_ = position; | 
| 292   for (StackCard* card in cards_.get()) { | 305   for (StackCard* card in cards_) { | 
| 293     LayoutRect layout = card.layout; | 306     LayoutRect layout = card.layout; | 
| 294     if (layoutIsVertical_) | 307     if (layoutIsVertical_) | 
| 295       layout.position.leading = position - 0.5 * layout.size.width; | 308       layout.position.leading = position - 0.5 * layout.size.width; | 
| 296     else | 309     else | 
| 297       layout.position.originY = position - 0.5 * layout.size.height; | 310       layout.position.originY = position - 0.5 * layout.size.height; | 
| 298     card.layout = layout; | 311     card.layout = layout; | 
| 299   } | 312   } | 
| 300 } | 313 } | 
| 301 | 314 | 
| 302 - (NSArray*)cards { | 315 - (NSArray*)cards { | 
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1121     CGFloat edgeOffset = endLimit_ - labelOffset; | 1134     CGFloat edgeOffset = endLimit_ - labelOffset; | 
| 1122     return cardOffset >= edgeOffset; | 1135     return cardOffset >= edgeOffset; | 
| 1123   } else { | 1136   } else { | 
| 1124     CGFloat separation = | 1137     CGFloat separation = | 
| 1125         [self distanceBetweenCardAtIndex:index andCardAtIndex:(index + 1)]; | 1138         [self distanceBetweenCardAtIndex:index andCardAtIndex:(index + 1)]; | 
| 1126     return separation <= labelOffset; | 1139     return separation <= labelOffset; | 
| 1127   } | 1140   } | 
| 1128 } | 1141 } | 
| 1129 | 1142 | 
| 1130 - (void)setSynchronizeCardViews:(BOOL)synchronizeViews { | 1143 - (void)setSynchronizeCardViews:(BOOL)synchronizeViews { | 
| 1131   for (StackCard* card in cards_.get()) { | 1144   for (StackCard* card in cards_) { | 
| 1132     card.synchronizeView = synchronizeViews; | 1145     card.synchronizeView = synchronizeViews; | 
| 1133   } | 1146   } | 
| 1134 } | 1147 } | 
| 1135 | 1148 | 
| 1136 - (BOOL)isInStartStack:(NSUInteger)index { | 1149 - (BOOL)isInStartStack:(NSUInteger)index { | 
| 1137   DCHECK(index < [cards_ count]); | 1150   DCHECK(index < [cards_ count]); | 
| 1138   return ((NSInteger)index <= lastStartStackCardIndex_); | 1151   return ((NSInteger)index <= lastStartStackCardIndex_); | 
| 1139 } | 1152 } | 
| 1140 | 1153 | 
| 1141 - (BOOL)isInEndStack:(NSUInteger)index { | 1154 - (BOOL)isInEndStack:(NSUInteger)index { | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1188     return 0; | 1201     return 0; | 
| 1189   return std::abs([self cardOffsetOnLayoutAxis:[cards_ firstObject]] - | 1202   return std::abs([self cardOffsetOnLayoutAxis:[cards_ firstObject]] - | 
| 1190                   startLimit_); | 1203                   startLimit_); | 
| 1191 } | 1204 } | 
| 1192 | 1205 | 
| 1193 - (NSUInteger)fannedStackCount { | 1206 - (NSUInteger)fannedStackCount { | 
| 1194   return floor((endLimit_ - startLimit_) / maxStagger_); | 1207   return floor((endLimit_ - startLimit_) / maxStagger_); | 
| 1195 } | 1208 } | 
| 1196 | 1209 | 
| 1197 @end | 1210 @end | 
| OLD | NEW | 
|---|