| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 | 654 |
| 655 PassRefPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea
) | 655 PassRefPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea
) |
| 656 { | 656 { |
| 657 return adoptRef(new ScrollAnimatorMac(scrollableArea)); | 657 return adoptRef(new ScrollAnimatorMac(scrollableArea)); |
| 658 } | 658 } |
| 659 | 659 |
| 660 ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea) | 660 ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea) |
| 661 : ScrollAnimator(scrollableArea) | 661 : ScrollAnimator(scrollableArea) |
| 662 , m_initialScrollbarPaintTimer(this, &ScrollAnimatorMac::initialScrollbarPai
ntTimerFired) | 662 , m_initialScrollbarPaintTimer(this, &ScrollAnimatorMac::initialScrollbarPai
ntTimerFired) |
| 663 , m_sendContentAreaScrolledTimer(this, &ScrollAnimatorMac::sendContentAreaSc
rolledTimerFired) | 663 , m_sendContentAreaScrolledTimer(this, &ScrollAnimatorMac::sendContentAreaSc
rolledTimerFired) |
| 664 #if USE(RUBBER_BANDING) | |
| 665 , m_scrollElasticityController(this) | |
| 666 , m_snapRubberBandTimer(this, &ScrollAnimatorMac::snapRubberBandTimerFired) | |
| 667 #endif | |
| 668 , m_haveScrolledSincePageLoad(false) | 664 , m_haveScrolledSincePageLoad(false) |
| 669 , m_needsScrollerStyleUpdate(false) | 665 , m_needsScrollerStyleUpdate(false) |
| 670 { | 666 { |
| 671 m_scrollAnimationHelperDelegate.adoptNS([[WebScrollAnimationHelperDelegate a
lloc] initWithScrollAnimator:this]); | 667 m_scrollAnimationHelperDelegate.adoptNS([[WebScrollAnimationHelperDelegate a
lloc] initWithScrollAnimator:this]); |
| 672 m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelpe
r") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]); | 668 m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelpe
r") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]); |
| 673 | 669 |
| 674 if (ScrollbarThemeMacCommon::isOverlayAPIAvailable()) { | 670 if (ScrollbarThemeMacCommon::isOverlayAPIAvailable()) { |
| 675 m_scrollbarPainterControllerDelegate.adoptNS([[WebScrollbarPainterContro
llerDelegate alloc] initWithScrollableArea:scrollableArea]); | 671 m_scrollbarPainterControllerDelegate.adoptNS([[WebScrollbarPainterContro
llerDelegate alloc] initWithScrollableArea:scrollableArea]); |
| 676 m_scrollbarPainterController = [[[NSClassFromString(@"NSScrollerImpPair"
) alloc] init] autorelease]; | 672 m_scrollbarPainterController = [[[NSClassFromString(@"NSScrollerImpPair"
) alloc] init] autorelease]; |
| 677 [m_scrollbarPainterController.get() setDelegate:m_scrollbarPainterContro
llerDelegate.get()]; | 673 [m_scrollbarPainterController.get() setDelegate:m_scrollbarPainterContro
llerDelegate.get()]; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 693 } | 689 } |
| 694 | 690 |
| 695 static bool scrollAnimationEnabledForSystem() | 691 static bool scrollAnimationEnabledForSystem() |
| 696 { | 692 { |
| 697 NSString* scrollAnimationDefaultsKey = | 693 NSString* scrollAnimationDefaultsKey = |
| 698 @"AppleScrollAnimationEnabled"; | 694 @"AppleScrollAnimationEnabled"; |
| 699 static bool enabled = [[NSUserDefaults standardUserDefaults] boolForKey:scro
llAnimationDefaultsKey]; | 695 static bool enabled = [[NSUserDefaults standardUserDefaults] boolForKey:scro
llAnimationDefaultsKey]; |
| 700 return enabled; | 696 return enabled; |
| 701 } | 697 } |
| 702 | 698 |
| 703 #if USE(RUBBER_BANDING) | |
| 704 static bool rubberBandingEnabledForSystem() | |
| 705 { | |
| 706 static bool initialized = false; | |
| 707 static bool enabled = true; | |
| 708 // Caches the result, which is consistent with other apps like the Finder, w
hich all | |
| 709 // require a restart after changing this default. | |
| 710 if (!initialized) { | |
| 711 // Uses -objectForKey: and not -boolForKey: in order to default to true
if the value wasn't set. | |
| 712 id value = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSScrol
lViewRubberbanding"]; | |
| 713 if ([value isKindOfClass:[NSNumber class]]) | |
| 714 enabled = [value boolValue]; | |
| 715 initialized = true; | |
| 716 } | |
| 717 return enabled; | |
| 718 } | |
| 719 #endif | |
| 720 | |
| 721 ScrollResultOneDimensional ScrollAnimatorMac::scroll(ScrollbarOrientation orient
ation, ScrollGranularity granularity, float step, float delta) | 699 ScrollResultOneDimensional ScrollAnimatorMac::scroll(ScrollbarOrientation orient
ation, ScrollGranularity granularity, float step, float delta) |
| 722 { | 700 { |
| 723 m_haveScrolledSincePageLoad = true; | 701 m_haveScrolledSincePageLoad = true; |
| 724 | 702 |
| 725 if (!scrollAnimationEnabledForSystem() || !m_scrollableArea->scrollAnimatorE
nabled()) | 703 if (!scrollAnimationEnabledForSystem() || !m_scrollableArea->scrollAnimatorE
nabled()) |
| 726 return ScrollAnimator::scroll(orientation, granularity, step, delta); | 704 return ScrollAnimator::scroll(orientation, granularity, step, delta); |
| 727 | 705 |
| 728 if (granularity == ScrollByPixel || granularity == ScrollByPrecisePixel) | 706 if (granularity == ScrollByPixel || granularity == ScrollByPrecisePixel) |
| 729 return ScrollAnimator::scroll(orientation, granularity, step, delta); | 707 return ScrollAnimator::scroll(orientation, granularity, step, delta); |
| 730 | 708 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 759 | 737 |
| 760 IntPoint minPos = m_scrollableArea->minimumScrollPosition(); | 738 IntPoint minPos = m_scrollableArea->minimumScrollPosition(); |
| 761 IntPoint maxPos = m_scrollableArea->maximumScrollPosition(); | 739 IntPoint maxPos = m_scrollableArea->maximumScrollPosition(); |
| 762 | 740 |
| 763 float newX = std::max<float>(std::min<float>(position.x(), maxPos.x()), minP
os.x()); | 741 float newX = std::max<float>(std::min<float>(position.x(), maxPos.x()), minP
os.x()); |
| 764 float newY = std::max<float>(std::min<float>(position.y(), maxPos.y()), minP
os.y()); | 742 float newY = std::max<float>(std::min<float>(position.y(), maxPos.y()), minP
os.y()); |
| 765 | 743 |
| 766 return FloatPoint(newX, newY); | 744 return FloatPoint(newX, newY); |
| 767 } | 745 } |
| 768 | 746 |
| 769 void ScrollAnimatorMac::adjustScrollPositionToBoundsIfNecessary() | |
| 770 { | |
| 771 bool currentlyConstrainsToContentEdge = m_scrollableArea->constrainsScrollin
gToContentEdge(); | |
| 772 m_scrollableArea->setConstrainsScrollingToContentEdge(true); | |
| 773 | |
| 774 IntPoint currentScrollPosition = absoluteScrollPosition(); | |
| 775 FloatPoint nearestPointWithinBounds = adjustScrollPositionIfNecessary(absolu
teScrollPosition()); | |
| 776 immediateScrollBy(nearestPointWithinBounds - currentScrollPosition); | |
| 777 | |
| 778 m_scrollableArea->setConstrainsScrollingToContentEdge(currentlyConstrainsToC
ontentEdge); | |
| 779 } | |
| 780 | |
| 781 void ScrollAnimatorMac::immediateScrollTo(const FloatPoint& newPosition) | 747 void ScrollAnimatorMac::immediateScrollTo(const FloatPoint& newPosition) |
| 782 { | 748 { |
| 783 FloatPoint adjustedPosition = adjustScrollPositionIfNecessary(newPosition); | 749 FloatPoint adjustedPosition = adjustScrollPositionIfNecessary(newPosition); |
| 784 | 750 |
| 785 bool positionChanged = adjustedPosition.x() != m_currentPosX || adjustedPosi
tion.y() != m_currentPosY; | 751 bool positionChanged = adjustedPosition.x() != m_currentPosX || adjustedPosi
tion.y() != m_currentPosY; |
| 786 if (!positionChanged && !scrollableArea()->scrollOriginChanged()) | 752 if (!positionChanged && !scrollableArea()->scrollOriginChanged()) |
| 787 return; | 753 return; |
| 788 | 754 |
| 789 FloatSize delta = FloatSize(adjustedPosition.x() - m_currentPosX, adjustedPo
sition.y() - m_currentPosY); | 755 FloatSize delta = FloatSize(adjustedPosition.x() - m_currentPosX, adjustedPo
sition.y() - m_currentPosY); |
| 790 | 756 |
| 791 m_currentPosX = adjustedPosition.x(); | 757 m_currentPosX = adjustedPosition.x(); |
| 792 m_currentPosY = adjustedPosition.y(); | 758 m_currentPosY = adjustedPosition.y(); |
| 793 notifyContentAreaScrolled(delta); | 759 notifyContentAreaScrolled(delta); |
| 794 notifyPositionChanged(); | 760 notifyPositionChanged(); |
| 795 } | 761 } |
| 796 | 762 |
| 797 bool ScrollAnimatorMac::isRubberBandInProgress() const | |
| 798 { | |
| 799 #if !USE(RUBBER_BANDING) | |
| 800 return false; | |
| 801 #else | |
| 802 return m_scrollElasticityController.isRubberBandInProgress(); | |
| 803 #endif | |
| 804 } | |
| 805 | |
| 806 void ScrollAnimatorMac::immediateScrollToPointForScrollAnimation(const FloatPoin
t& newPosition) | 763 void ScrollAnimatorMac::immediateScrollToPointForScrollAnimation(const FloatPoin
t& newPosition) |
| 807 { | 764 { |
| 808 ASSERT(m_scrollAnimationHelper); | 765 ASSERT(m_scrollAnimationHelper); |
| 809 immediateScrollTo(newPosition); | 766 immediateScrollTo(newPosition); |
| 810 } | 767 } |
| 811 | 768 |
| 812 void ScrollAnimatorMac::contentAreaWillPaint() const | 769 void ScrollAnimatorMac::contentAreaWillPaint() const |
| 813 { | 770 { |
| 814 if (!scrollableArea()->scrollbarsCanBeActive()) | 771 if (!scrollableArea()->scrollbarsCanBeActive()) |
| 815 return; | 772 return; |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 m_haveScrolledSincePageLoad = true; | 1026 m_haveScrolledSincePageLoad = true; |
| 1070 | 1027 |
| 1071 if (phase == PlatformWheelEventPhaseBegan) | 1028 if (phase == PlatformWheelEventPhaseBegan) |
| 1072 didBeginScrollGesture(); | 1029 didBeginScrollGesture(); |
| 1073 else if (phase == PlatformWheelEventPhaseEnded || phase == PlatformWheelEven
tPhaseCancelled) | 1030 else if (phase == PlatformWheelEventPhaseEnded || phase == PlatformWheelEven
tPhaseCancelled) |
| 1074 didEndScrollGesture(); | 1031 didEndScrollGesture(); |
| 1075 else if (phase == PlatformWheelEventPhaseMayBegin) | 1032 else if (phase == PlatformWheelEventPhaseMayBegin) |
| 1076 mayBeginScrollGesture(); | 1033 mayBeginScrollGesture(); |
| 1077 } | 1034 } |
| 1078 | 1035 |
| 1079 #if USE(RUBBER_BANDING) | |
| 1080 ScrollResult ScrollAnimatorMac::handleWheelEvent(const PlatformWheelEvent& wheel
Event) | |
| 1081 { | |
| 1082 m_haveScrolledSincePageLoad = true; | |
| 1083 | |
| 1084 if (!wheelEvent.hasPreciseScrollingDeltas() || !rubberBandingEnabledForSyste
m() || m_scrollableArea->rubberBandingOnCompositorThread()) | |
| 1085 return ScrollAnimator::handleWheelEvent(wheelEvent); | |
| 1086 | |
| 1087 // FIXME: This is somewhat roundabout hack to allow forwarding wheel events | |
| 1088 // up to the parent scrollable area. It takes advantage of the fact that | |
| 1089 // the base class implementation of handleWheelEvent will not accept the | |
| 1090 // wheel event if there is nowhere to scroll. | |
| 1091 if (fabsf(wheelEvent.deltaY()) >= fabsf(wheelEvent.deltaX())) { | |
| 1092 if (!allowsVerticalStretching()) | |
| 1093 return ScrollAnimator::handleWheelEvent(wheelEvent); | |
| 1094 } else { | |
| 1095 if (!allowsHorizontalStretching()) | |
| 1096 return ScrollAnimator::handleWheelEvent(wheelEvent); | |
| 1097 } | |
| 1098 | |
| 1099 bool didHandleEvent = m_scrollElasticityController.handleWheelEvent(wheelEve
nt); | |
| 1100 | |
| 1101 // The elasticity controller can return false on a phase end event if rubber
banding wasn't in progress. | |
| 1102 // In this case, the wheel phase must still be handled so that that overlay
scroll bars get hidden. | |
| 1103 if (didHandleEvent || wheelEvent.phase() == PlatformWheelEventPhaseEnded ||
wheelEvent.phase() == PlatformWheelEventPhaseCancelled) | |
| 1104 handleWheelEventPhase(wheelEvent.phase()); | |
| 1105 | |
| 1106 // Rubber banding in Blink does not exist anymore, so the fact that this doe
s not compute the unused | |
| 1107 // scroll deltas does not matter. This code will be deleted soon. | |
| 1108 return ScrollResult(didHandleEvent); | |
| 1109 } | |
| 1110 | |
| 1111 bool ScrollAnimatorMac::pinnedInDirection(float deltaX, float deltaY) | |
| 1112 { | |
| 1113 FloatSize limitDelta; | |
| 1114 if (fabsf(deltaY) >= fabsf(deltaX)) { | |
| 1115 if (deltaY < 0) { | |
| 1116 // We are trying to scroll up. Make sure we are not pinned to the t
op | |
| 1117 limitDelta.setHeight(m_scrollableArea->visibleContentRect().y() + +
m_scrollableArea->scrollOrigin().y()); | |
| 1118 } else { | |
| 1119 // We are trying to scroll down. Make sure we are not pinned to the
bottom | |
| 1120 limitDelta.setHeight(m_scrollableArea->contentsSize().height() - (m_
scrollableArea->visibleContentRect().maxY() + m_scrollableArea->scrollOrigin().y
())); | |
| 1121 } | |
| 1122 } else if (deltaX != 0) { | |
| 1123 if (deltaX < 0) { | |
| 1124 // We are trying to scroll left. Make sure we are not pinned to the
left | |
| 1125 limitDelta.setWidth(m_scrollableArea->visibleContentRect().x() + m_s
crollableArea->scrollOrigin().x()); | |
| 1126 } else { | |
| 1127 // We are trying to scroll right. Make sure we are not pinned to th
e right | |
| 1128 limitDelta.setWidth(m_scrollableArea->contentsSize().width() - (m_sc
rollableArea->visibleContentRect().maxX() + m_scrollableArea->scrollOrigin().x()
)); | |
| 1129 } | |
| 1130 } | |
| 1131 | |
| 1132 if ((deltaX != 0 || deltaY != 0) && (limitDelta.width() < 1 && limitDelta.he
ight() < 1)) | |
| 1133 return true; | |
| 1134 return false; | |
| 1135 } | |
| 1136 | |
| 1137 bool ScrollAnimatorMac::allowsVerticalStretching() | |
| 1138 { | |
| 1139 switch (m_scrollableArea->verticalScrollElasticity()) { | |
| 1140 case ScrollElasticityAutomatic: { | |
| 1141 Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); | |
| 1142 Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); | |
| 1143 return (((vScroller && vScroller->enabled()) || (!hScroller || !hScrolle
r->enabled()))); | |
| 1144 } | |
| 1145 case ScrollElasticityNone: | |
| 1146 return false; | |
| 1147 case ScrollElasticityAllowed: | |
| 1148 return true; | |
| 1149 } | |
| 1150 | |
| 1151 ASSERT_NOT_REACHED(); | |
| 1152 return false; | |
| 1153 } | |
| 1154 | |
| 1155 bool ScrollAnimatorMac::allowsHorizontalStretching() | |
| 1156 { | |
| 1157 switch (m_scrollableArea->horizontalScrollElasticity()) { | |
| 1158 case ScrollElasticityAutomatic: { | |
| 1159 Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); | |
| 1160 Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); | |
| 1161 return (((hScroller && hScroller->enabled()) || (!vScroller || !vScrolle
r->enabled()))); | |
| 1162 } | |
| 1163 case ScrollElasticityNone: | |
| 1164 return false; | |
| 1165 case ScrollElasticityAllowed: | |
| 1166 return true; | |
| 1167 } | |
| 1168 | |
| 1169 ASSERT_NOT_REACHED(); | |
| 1170 return false; | |
| 1171 } | |
| 1172 | |
| 1173 IntSize ScrollAnimatorMac::stretchAmount() | |
| 1174 { | |
| 1175 return m_scrollableArea->overhangAmount(); | |
| 1176 } | |
| 1177 | |
| 1178 bool ScrollAnimatorMac::pinnedInDirection(const FloatSize& direction) | |
| 1179 { | |
| 1180 return pinnedInDirection(direction.width(), direction.height()); | |
| 1181 } | |
| 1182 | |
| 1183 bool ScrollAnimatorMac::canScrollHorizontally() | |
| 1184 { | |
| 1185 Scrollbar* scrollbar = m_scrollableArea->horizontalScrollbar(); | |
| 1186 if (!scrollbar) | |
| 1187 return false; | |
| 1188 return scrollbar->enabled(); | |
| 1189 } | |
| 1190 | |
| 1191 bool ScrollAnimatorMac::canScrollVertically() | |
| 1192 { | |
| 1193 Scrollbar* scrollbar = m_scrollableArea->verticalScrollbar(); | |
| 1194 if (!scrollbar) | |
| 1195 return false; | |
| 1196 return scrollbar->enabled(); | |
| 1197 } | |
| 1198 | |
| 1199 IntPoint ScrollAnimatorMac::absoluteScrollPosition() | |
| 1200 { | |
| 1201 return m_scrollableArea->visibleContentRect().location() + m_scrollableArea-
>scrollOrigin(); | |
| 1202 } | |
| 1203 | |
| 1204 void ScrollAnimatorMac::immediateScrollByWithoutContentEdgeConstraints(const Flo
atSize& delta) | |
| 1205 { | |
| 1206 m_scrollableArea->setConstrainsScrollingToContentEdge(false); | |
| 1207 immediateScrollBy(delta); | |
| 1208 m_scrollableArea->setConstrainsScrollingToContentEdge(true); | |
| 1209 } | |
| 1210 | |
| 1211 void ScrollAnimatorMac::immediateScrollBy(const FloatSize& delta) | |
| 1212 { | |
| 1213 FloatPoint newPos = adjustScrollPositionIfNecessary(FloatPoint(m_currentPosX
, m_currentPosY) + delta); | |
| 1214 if (newPos.x() == m_currentPosX && newPos.y() == m_currentPosY) | |
| 1215 return; | |
| 1216 | |
| 1217 FloatSize adjustedDelta = FloatSize(newPos.x() - m_currentPosX, newPos.y() -
m_currentPosY); | |
| 1218 | |
| 1219 m_currentPosX = newPos.x(); | |
| 1220 m_currentPosY = newPos.y(); | |
| 1221 notifyContentAreaScrolled(adjustedDelta); | |
| 1222 notifyPositionChanged(); | |
| 1223 } | |
| 1224 | |
| 1225 void ScrollAnimatorMac::startSnapRubberbandTimer() | |
| 1226 { | |
| 1227 m_snapRubberBandTimer.startRepeating(1.0 / 60.0, FROM_HERE); | |
| 1228 } | |
| 1229 | |
| 1230 void ScrollAnimatorMac::stopSnapRubberbandTimer() | |
| 1231 { | |
| 1232 m_snapRubberBandTimer.stop(); | |
| 1233 } | |
| 1234 | |
| 1235 void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) | |
| 1236 { | |
| 1237 m_scrollElasticityController.snapRubberBandTimerFired(); | |
| 1238 } | |
| 1239 #endif | |
| 1240 | |
| 1241 void ScrollAnimatorMac::setIsActive() | 1036 void ScrollAnimatorMac::setIsActive() |
| 1242 { | 1037 { |
| 1243 if (!ScrollbarThemeMacCommon::isOverlayAPIAvailable()) | 1038 if (!ScrollbarThemeMacCommon::isOverlayAPIAvailable()) |
| 1244 return; | 1039 return; |
| 1245 | 1040 |
| 1246 if (!m_needsScrollerStyleUpdate) | 1041 if (!m_needsScrollerStyleUpdate) |
| 1247 return; | 1042 return; |
| 1248 | 1043 |
| 1249 updateScrollerStyle(); | 1044 updateScrollerStyle(); |
| 1250 } | 1045 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 return; | 1158 return; |
| 1364 | 1159 |
| 1365 m_visibleScrollerThumbRect = rectInViewCoordinates; | 1160 m_visibleScrollerThumbRect = rectInViewCoordinates; |
| 1366 } | 1161 } |
| 1367 | 1162 |
| 1368 bool ScrollAnimatorMac::canUseCoordinatedScrollbar() { | 1163 bool ScrollAnimatorMac::canUseCoordinatedScrollbar() { |
| 1369 return ScrollbarThemeMacCommon::isOverlayAPIAvailable(); | 1164 return ScrollbarThemeMacCommon::isOverlayAPIAvailable(); |
| 1370 } | 1165 } |
| 1371 | 1166 |
| 1372 } // namespace blink | 1167 } // namespace blink |
| OLD | NEW |