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 |