2010-09-08 Peter Kasting <pkasting@google.com>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Sep 2010 19:31:47 +0000 (19:31 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Sep 2010 19:31:47 +0000 (19:31 +0000)
        Reviewed by David Hyatt.

        Add smooth scrolling framework, and a Windows implementation.
        https://bugs.webkit.org/show_bug.cgi?id=32356

        * wscript: Add Windows ScrollAnimator.
2010-09-08  Peter Kasting  <pkasting@google.com>

        Reviewed by David Hyatt.

        Add smooth scrolling framework, and a Windows implementation.
        https://bugs.webkit.org/show_bug.cgi?id=32356

        * CMakeLists.txt: Add ScrollAnimator.
        * GNUmakefile.am: Add ScrollAnimator.
        * WebCore.gyp/WebCore.gyp: Add Windows ScrollAnimator.
        * WebCore.gypi: Add ScrollAnimator.
        * WebCore.pro: Add ScrollAnimator.
        * WebCore.vcproj/WebCore.vcproj: Add ScrollAnimator.
        * WebCore.xcodeproj/project.pbxproj: Add ScrollAnimator.
        * platform/ScrollAnimator.cpp: Added base implementation that does no animation.
        (WebCore::ScrollAnimator::create):
        (WebCore::ScrollAnimator::scroll):
        (WebCore::ScrollAnimator::setScrollPositionAndStopAnimation):
        * platform/ScrollAnimator.h: Added base implementation that does no animation.
        (WebCore::ScrollAnimator::ScrollAnimator):
        (WebCore::ScrollAnimator::~ScrollAnimator):
        * platform/ScrollAnimatorWin.cpp: Added Windows subclass that animates scrolls.
        (WebCore::ScrollAnimator::create):
        (WebCore::ScrollAnimatorWin::PerAxisData::PerAxisData):
        (WebCore::ScrollAnimatorWin::ScrollAnimatorWin):
        (WebCore::ScrollAnimatorWin::~ScrollAnimatorWin):
        (WebCore::ScrollAnimatorWin::scroll):
        (WebCore::ScrollAnimatorWin::setScrollPositionAndStopAnimation):
        (WebCore::ScrollAnimatorWin::accelerationTime):
        (WebCore::ScrollAnimatorWin::animationTimerFired):
        (WebCore::ScrollAnimatorWin::stopAnimationTimerIfNeeded):
        (WebCore::ScrollAnimatorWin::animateScroll):
        * platform/ScrollAnimatorWin.h: Added Windows subclass that animates scrolls.
        * platform/ScrollView.cpp: Implement new ScrollbarClient functions.  Allow wheel scrolls to be animated.
        (WebCore::ScrollView::scrollSize):
        (WebCore::ScrollView::setScrollOffsetFromAnimation):
        (WebCore::ScrollView::updateScrollbars):
        (WebCore::ScrollView::wheelEvent):
        * platform/ScrollView.h: Implement new ScrollbarClient functions.
        * platform/Scrollbar.cpp: Allow ScrollAnimator to handle scrolls if present.
        (WebCore::Scrollbar::setValue):
        (WebCore::Scrollbar::scroll):
        (WebCore::Scrollbar::moveThumb):
        (WebCore::Scrollbar::setCurrentPos):
        (WebCore::Scrollbar::mouseMoved):
        * platform/Scrollbar.h:
        * platform/ScrollbarClient.cpp: Added to avoid having to make ScrollAnimator.h non-private.
        (WebCore::ScrollbarClient::ScrollbarClient):
        (WebCore::ScrollbarClient::~ScrollbarClient):
        (WebCore::ScrollbarClient::scroll):
        (WebCore::ScrollbarClient::setScrollPositionAndStopAnimation):
        * platform/ScrollbarClient.h: Add hooks for ScrollAnimator.
        (WebCore::ScrollbarClient::convertFromScrollbarToContainingView):
        (WebCore::ScrollbarClient::convertFromContainingViewToScrollbar):
        * platform/gtk/MainFrameScrollbarGtk.cpp:
        (MainFrameScrollbarGtk::gtkValueChanged):
        * platform/qt/ScrollbarQt.cpp: Use scroll() in preference to setValue().
        (WebCore::Scrollbar::contextMenu):
        * platform/win/PopupMenuWin.cpp: Implement new ScrollbarClient functions.
        (WebCore::PopupMenuWin::scrollSize):
        (WebCore::PopupMenuWin::setScrollOffsetFromAnimation):
        * platform/win/PopupMenuWin.h: Implement new ScrollbarClient functions.
        * rendering/RenderDataGrid.cpp: Implement new ScrollbarClient functions.
        (WebCore::RenderDataGrid::scrollSize):
        (WebCore::RenderDataGrid::setScrollOffsetFromAnimation):
        * rendering/RenderDataGrid.h: Implement new ScrollbarClient functions.
        * rendering/RenderLayer.cpp: Implement new ScrollbarClient functions.
        (WebCore::RenderLayer::scrollToOffset):
        (WebCore::RenderLayer::scrollSize):
        (WebCore::RenderLayer::setScrollOffsetFromAnimation):
        (WebCore::RenderLayer::updateScrollInfoAfterLayout):
        * rendering/RenderLayer.h: Implement new ScrollbarClient functions.
        * rendering/RenderListBox.cpp: Implement new ScrollbarClient functions.
        (WebCore::RenderListBox::scrollToRevealElementAtListIndex):
        (WebCore::RenderListBox::scrollSize):
        (WebCore::RenderListBox::setScrollOffsetFromAnimation):
        (WebCore::RenderListBox::setScrollTop):
        * rendering/RenderListBox.h: Implement new ScrollbarClient functions.
2010-09-08  Peter Kasting  <pkasting@google.com>

        Reviewed by David Hyatt.

        Add smooth scrolling framework, and a Windows implementation.
        https://bugs.webkit.org/show_bug.cgi?id=32356

        * src/WebScrollbarImpl.cpp: Plumb new ScrollbarClient functions.  Allow wheel scrolls to be animated.
        (WebKit::WebScrollbarImpl::setLocation):
        (WebKit::WebScrollbarImpl::setValue):
        (WebKit::WebScrollbarImpl::scroll):
        (WebKit::WebScrollbarImpl::onMouseWheel):
        (WebKit::WebScrollbarImpl::onKeyDown):
        (WebKit::WebScrollbarImpl::setScrollOffsetFromAnimation):
        * src/WebScrollbarImpl.h: Plumb new ScrollbarClient functions.
        * src/win/WebInputEventFactory.cpp: Update comments now that we have smooth scrolling.
        (WebKit::WebInputEventFactory::mouseWheelEvent):
2010-09-08  Peter Kasting  <pkasting@google.com>

        Reviewed by David Hyatt.

        Add smooth scrolling framework, and a Windows implementation.
        https://bugs.webkit.org/show_bug.cgi?id=32356

        * Api/qwebframe.cpp:
        (QWebFrame::setScrollBarValue):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67001 268f45cc-cd09-0410-ab3c-d52691b4dbfc

36 files changed:
ChangeLog
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gyp/WebCore.gyp
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/platform/ScrollAnimator.cpp [new file with mode: 0644]
WebCore/platform/ScrollAnimator.h [new file with mode: 0644]
WebCore/platform/ScrollAnimatorWin.cpp [new file with mode: 0644]
WebCore/platform/ScrollAnimatorWin.h [new file with mode: 0644]
WebCore/platform/ScrollView.cpp
WebCore/platform/ScrollView.h
WebCore/platform/Scrollbar.cpp
WebCore/platform/Scrollbar.h
WebCore/platform/ScrollbarClient.cpp [new file with mode: 0644]
WebCore/platform/ScrollbarClient.h
WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
WebCore/platform/qt/ScrollbarQt.cpp
WebCore/platform/win/PopupMenuWin.cpp
WebCore/platform/win/PopupMenuWin.h
WebCore/rendering/RenderDataGrid.cpp
WebCore/rendering/RenderDataGrid.h
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayer.h
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderListBox.h
WebKit/chromium/ChangeLog
WebKit/chromium/src/WebScrollbarImpl.cpp
WebKit/chromium/src/WebScrollbarImpl.h
WebKit/chromium/src/win/WebInputEventFactory.cpp
WebKit/qt/Api/qwebframe.cpp
WebKit/qt/ChangeLog
wscript

index 6face08..ad2113a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-08  Peter Kasting  <pkasting@google.com>
+
+        Reviewed by David Hyatt.
+
+        Add smooth scrolling framework, and a Windows implementation.
+        https://bugs.webkit.org/show_bug.cgi?id=32356
+
+        * wscript: Add Windows ScrollAnimator.
+
 2010-09-08  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Unreviewed buildfix after r66972.
index 885d801..ade5880 100644 (file)
@@ -1200,7 +1200,9 @@ SET(WebCore_SOURCES
     platform/LinkHash.cpp
     platform/Logging.cpp
     platform/MIMETypeRegistry.cpp
+    platform/ScrollAnimator.cpp
     platform/Scrollbar.cpp
+    platform/ScrollbarClient.cpp
     platform/ScrollbarThemeComposite.cpp
     platform/ScrollView.cpp
     platform/SharedBuffer.cpp
index 9ebc12d..f1273c8 100644 (file)
@@ -1,3 +1,82 @@
+2010-09-08  Peter Kasting  <pkasting@google.com>
+
+        Reviewed by David Hyatt.
+
+        Add smooth scrolling framework, and a Windows implementation.
+        https://bugs.webkit.org/show_bug.cgi?id=32356
+
+        * CMakeLists.txt: Add ScrollAnimator.
+        * GNUmakefile.am: Add ScrollAnimator.
+        * WebCore.gyp/WebCore.gyp: Add Windows ScrollAnimator.
+        * WebCore.gypi: Add ScrollAnimator.
+        * WebCore.pro: Add ScrollAnimator.
+        * WebCore.vcproj/WebCore.vcproj: Add ScrollAnimator.
+        * WebCore.xcodeproj/project.pbxproj: Add ScrollAnimator.
+        * platform/ScrollAnimator.cpp: Added base implementation that does no animation.
+        (WebCore::ScrollAnimator::create):
+        (WebCore::ScrollAnimator::scroll):
+        (WebCore::ScrollAnimator::setScrollPositionAndStopAnimation):
+        * platform/ScrollAnimator.h: Added base implementation that does no animation.
+        (WebCore::ScrollAnimator::ScrollAnimator):
+        (WebCore::ScrollAnimator::~ScrollAnimator):
+        * platform/ScrollAnimatorWin.cpp: Added Windows subclass that animates scrolls.
+        (WebCore::ScrollAnimator::create):
+        (WebCore::ScrollAnimatorWin::PerAxisData::PerAxisData):
+        (WebCore::ScrollAnimatorWin::ScrollAnimatorWin):
+        (WebCore::ScrollAnimatorWin::~ScrollAnimatorWin):
+        (WebCore::ScrollAnimatorWin::scroll):
+        (WebCore::ScrollAnimatorWin::setScrollPositionAndStopAnimation):
+        (WebCore::ScrollAnimatorWin::accelerationTime):
+        (WebCore::ScrollAnimatorWin::animationTimerFired):
+        (WebCore::ScrollAnimatorWin::stopAnimationTimerIfNeeded):
+        (WebCore::ScrollAnimatorWin::animateScroll):
+        * platform/ScrollAnimatorWin.h: Added Windows subclass that animates scrolls.
+        * platform/ScrollView.cpp: Implement new ScrollbarClient functions.  Allow wheel scrolls to be animated.
+        (WebCore::ScrollView::scrollSize):
+        (WebCore::ScrollView::setScrollOffsetFromAnimation):
+        (WebCore::ScrollView::updateScrollbars):
+        (WebCore::ScrollView::wheelEvent):
+        * platform/ScrollView.h: Implement new ScrollbarClient functions.
+        * platform/Scrollbar.cpp: Allow ScrollAnimator to handle scrolls if present.
+        (WebCore::Scrollbar::setValue):
+        (WebCore::Scrollbar::scroll):
+        (WebCore::Scrollbar::moveThumb):
+        (WebCore::Scrollbar::setCurrentPos):
+        (WebCore::Scrollbar::mouseMoved):
+        * platform/Scrollbar.h:
+        * platform/ScrollbarClient.cpp: Added to avoid having to make ScrollAnimator.h non-private.
+        (WebCore::ScrollbarClient::ScrollbarClient):
+        (WebCore::ScrollbarClient::~ScrollbarClient):
+        (WebCore::ScrollbarClient::scroll):
+        (WebCore::ScrollbarClient::setScrollPositionAndStopAnimation):
+        * platform/ScrollbarClient.h: Add hooks for ScrollAnimator.
+        (WebCore::ScrollbarClient::convertFromScrollbarToContainingView):
+        (WebCore::ScrollbarClient::convertFromContainingViewToScrollbar):
+        * platform/gtk/MainFrameScrollbarGtk.cpp:
+        (MainFrameScrollbarGtk::gtkValueChanged):
+        * platform/qt/ScrollbarQt.cpp: Use scroll() in preference to setValue().
+        (WebCore::Scrollbar::contextMenu):
+        * platform/win/PopupMenuWin.cpp: Implement new ScrollbarClient functions.
+        (WebCore::PopupMenuWin::scrollSize):
+        (WebCore::PopupMenuWin::setScrollOffsetFromAnimation):
+        * platform/win/PopupMenuWin.h: Implement new ScrollbarClient functions.
+        * rendering/RenderDataGrid.cpp: Implement new ScrollbarClient functions.
+        (WebCore::RenderDataGrid::scrollSize):
+        (WebCore::RenderDataGrid::setScrollOffsetFromAnimation):
+        * rendering/RenderDataGrid.h: Implement new ScrollbarClient functions.
+        * rendering/RenderLayer.cpp: Implement new ScrollbarClient functions.
+        (WebCore::RenderLayer::scrollToOffset):
+        (WebCore::RenderLayer::scrollSize):
+        (WebCore::RenderLayer::setScrollOffsetFromAnimation):
+        (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+        * rendering/RenderLayer.h: Implement new ScrollbarClient functions.
+        * rendering/RenderListBox.cpp: Implement new ScrollbarClient functions.
+        (WebCore::RenderListBox::scrollToRevealElementAtListIndex):
+        (WebCore::RenderListBox::scrollSize):
+        (WebCore::RenderListBox::setScrollOffsetFromAnimation):
+        (WebCore::RenderListBox::setScrollTop):
+        * rendering/RenderListBox.h: Implement new ScrollbarClient functions.
+
 2010-09-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         Reviewed by Tony Chang.
index 0f57413..8297365 100644 (file)
@@ -1953,6 +1953,8 @@ webcore_sources += \
        WebCore/platform/PopupMenuStyle.h \
        WebCore/platform/PurgeableBuffer.h \
        WebCore/platform/SSLKeyGenerator.h \
+       WebCore/platform/ScrollAnimator.cpp \
+       WebCore/platform/ScrollAnimator.h \
        WebCore/platform/ScrollTypes.h \
        WebCore/platform/ScrollView.cpp \
        WebCore/platform/ScrollView.h \
@@ -1960,6 +1962,7 @@ webcore_sources += \
        WebCore/platform/SchemeRegistry.h \
        WebCore/platform/Scrollbar.cpp \
        WebCore/platform/Scrollbar.h \
+       WebCore/platform/ScrollbarClient.cpp \
        WebCore/platform/ScrollbarClient.h \
        WebCore/platform/ScrollbarTheme.h \
        WebCore/platform/ScrollbarThemeComposite.cpp \
@@ -2573,6 +2576,8 @@ endif
 
 if TARGET_WIN32
 webcore_sources += \
+       WebCore/platform/ScrollAnimatorWin.cpp \
+       WebCore/platform/ScrollAnimatorWin.h \
        WebCore/plugins/win/PluginDatabaseWin.cpp \
        WebCore/plugins/win/PluginMessageThrottlerWin.cpp \
        WebCore/plugins/win/PluginMessageThrottlerWin.h
index 595034e..c4f1f44 100644 (file)
           'sources/': [
             ['exclude', 'Posix\\.cpp$'],
             ['include', '/opentype/'],
+            ['include', '/ScrollAnimatorWin\\.cpp$'],
+            ['include', '/ScrollAnimatorWin\\.h$'],
             ['include', '/SkiaFontWin\\.cpp$'],
             ['include', '/TransparencyWin\\.cpp$'],
           ],
index c759794..7ee7ab4 100644 (file)
             'platform/PopupMenuStyle.h',
             'platform/PurgeableBuffer.h',
             'platform/SSLKeyGenerator.h',
+            'platform/ScrollAnimator.cpp',
+            'platform/ScrollAnimator.h',
+            'platform/ScrollAnimatorWin.cpp',
+            'platform/ScrollAnimatorWin.h',
             'platform/ScrollTypes.h',
             'platform/ScrollView.cpp',
             'platform/ScrollView.h',
             'platform/SchemeRegistry.h',
             'platform/Scrollbar.cpp',
             'platform/Scrollbar.h',
+            'platform/ScrollbarClient.cpp',
             'platform/ScrollbarClient.h',
             'platform/ScrollbarTheme.h',
             'platform/ScrollbarThemeComposite.cpp',
index ea6e901..a72ecac 100644 (file)
@@ -959,7 +959,9 @@ SOURCES += \
     platform/network/ResourceResponseBase.cpp \
     platform/text/RegularExpression.cpp \
     platform/SchemeRegistry.cpp \
+    platform/ScrollAnimator.cpp \
     platform/Scrollbar.cpp \
+    platform/ScrollbarClient.cpp \
     platform/ScrollbarThemeComposite.cpp \
     platform/ScrollView.cpp \
     platform/text/SegmentedString.cpp \
@@ -1789,7 +1791,9 @@ HEADERS += \
     platform/qt/QtStyleOptionWebComboBox.h \
     platform/qt/RenderThemeQt.h \
     platform/qt/ScrollbarThemeQt.h \
+    platform/ScrollAnimator.h \
     platform/Scrollbar.h \
+    platform/ScrollbarClient.h \
     platform/ScrollbarThemeComposite.h \
     platform/ScrollView.h \
     platform/SearchPopupMenu.h \
@@ -2350,8 +2354,12 @@ maemo5 {
 }
 
 
-    win32-*|wince*: SOURCES += platform/win/SystemTimeWin.cpp \
-                               platform/graphics/win/TransformationMatrixWin.cpp
+    win32-*|wince* {
+        HEADERS += platform/ScrollAnimatorWin.h
+        SOURCES += platform/ScrollAnimatorWin.cpp \
+                   platform/win/SystemTimeWin.cpp \
+                   platform/graphics/win/TransformationMatrixWin.cpp
+    }
 
     mac {
         SOURCES += \
index 047bd47..b588548 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\platform\ScrollAnimator.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\platform\ScrollAnimator.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\platform\ScrollAnimatorWin.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\platform\ScrollAnimatorWin.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\platform\Scrollbar.cpp"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\platform\ScrollbarClient.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\platform\ScrollbarClient.h"\r
                                >\r
                        </File>\r
index a52439e..46ebb09 100644 (file)
                BC99812E0DBE807A008CE9EF /* DOMAbstractViewFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = BC99812D0DBE807A008CE9EF /* DOMAbstractViewFrame.h */; };
                BC9ADD230CC4032600098C4C /* WebKitCSSTransformValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9ADD220CC4032600098C4C /* WebKitCSSTransformValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC9ADD800CC4092200098C4C /* WebKitCSSTransformValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9ADD7F0CC4092200098C4C /* WebKitCSSTransformValue.cpp */; };
-               BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC9BC64D0E7C4889008B9849 /* ScrollbarClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */; settings = {ATTRIBUTES = (Private, ); }; };
+               BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCA169A20BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */; };
                BCA169A30BFD55B40019CA76 /* JSHTMLTableCaptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */; };
                BCA2B061105047600043BD1C /* UserScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA2B0601050475F0043BD1C /* UserScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C5EBDD84105EDDEC0056816F /* StorageEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */; };
                C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
                C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
+               CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */; };
+               CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; };
                CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
                CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE057FA41220731100A476D5 /* DocumentMarkerController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC99812D0DBE807A008CE9EF /* DOMAbstractViewFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAbstractViewFrame.h; sourceTree = "<group>"; };
                BC9ADD220CC4032600098C4C /* WebKitCSSTransformValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebKitCSSTransformValue.h; sourceTree = "<group>"; };
                BC9ADD7F0CC4092200098C4C /* WebKitCSSTransformValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSTransformValue.cpp; sourceTree = "<group>"; };
-               BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarClient.h; sourceTree = "<group>"; };
+               BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarClient.cpp; sourceTree = "<group>"; };
+               BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarClient.h; sourceTree = "<group>"; };
                BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableCaptionElement.cpp; sourceTree = "<group>"; };
                BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLTableCaptionElement.h; sourceTree = "<group>"; };
                BCA2B0601050475F0043BD1C /* UserScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserScript.h; sourceTree = "<group>"; };
                C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageEventDispatcher.h; sourceTree = "<group>"; };
                C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifySelectionListLevel.h; sourceTree = "<group>"; };
                C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
+               CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; };
+               CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
                CD4E0AFA11F7BC27009D3811 /* fullscreen.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreen.css; sourceTree = "<group>"; };
                CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptControllerBase.h; sourceTree = "<group>"; };
                CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
                                1C63A2460F71646600C09D5A /* RunLoopTimer.h */,
                                5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */,
                                5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
+                               CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
+                               CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */,
                                BC7B2AF80450824100A8000F /* Scrollbar.h */,
-                               BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */,
+                               BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */,
+                               BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */,
                                BC8B854A0E7C7F5600AB6984 /* ScrollbarTheme.h */,
                                BC1402880E83680800319717 /* ScrollbarThemeComposite.cpp */,
                                BC1402890E83680800319717 /* ScrollbarThemeComposite.h */,
                                416F45F00ED7B311008215B6 /* ScriptString.h in Headers */,
                                934CC0E20ED39D6F00A658F2 /* ScriptValue.h in Headers */,
                                228C284510D82500009D0D0E /* ScriptWrappable.h in Headers */,
+                               CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
                                93F199B808245E59001E9ABC /* Scrollbar.h in Headers */,
                                BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */,
                                BC8B854B0E7C7F5600AB6984 /* ScrollbarTheme.h in Headers */,
                                9F72305011184B4100AD0126 /* ScriptProfiler.cpp in Sources */,
                                4127D5370F8AAB1D00E424F5 /* ScriptState.cpp in Sources */,
                                934CC0E10ED39D6F00A658F2 /* ScriptValue.cpp in Sources */,
+                               CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */,
                                BCAA90C30A7EBA60008B1229 /* Scrollbar.cpp in Sources */,
+                               BC9BC64D0E7C4889008B9849 /* ScrollbarClient.cpp in Sources */,
                                BC14028A0E83680800319717 /* ScrollbarThemeComposite.cpp in Sources */,
                                BCEF869F0E844E9D00A85CD5 /* ScrollbarThemeMac.mm in Sources */,
                                5D925B670F64D4DD00B847F0 /* ScrollBehavior.cpp in Sources */,
diff --git a/WebCore/platform/ScrollAnimator.cpp b/WebCore/platform/ScrollAnimator.cpp
new file mode 100644 (file)
index 0000000..a852e6b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollAnimator.h"
+
+#include "ScrollbarClient.h"
+#include <algorithm>
+
+namespace WebCore {
+
+#if !OS(WINDOWS)
+ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client)
+{
+    return new ScrollAnimator(client);
+}
+#endif
+
+bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier)
+{
+    float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY;
+    float newPos = std::max(std::min(*currentPos + (step * multiplier), static_cast<float>(m_client->scrollSize(orientation))), 0.0f);
+    if (*currentPos == newPos)
+        return false;
+    *currentPos = newPos;
+    m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
+    return true;
+}
+
+void ScrollAnimator::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+    if (orientation == HorizontalScrollbar)
+        m_currentPosX = pos;
+    else
+        m_currentPosY = pos;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ScrollAnimator.h b/WebCore/platform/ScrollAnimator.h
new file mode 100644 (file)
index 0000000..084afc7
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScrollAnimator_h
+#define ScrollAnimator_h
+
+#include "ScrollTypes.h"
+
+namespace WebCore {
+
+class ScrollbarClient;
+
+class ScrollAnimator {
+public:
+    static ScrollAnimator* create(ScrollbarClient*);
+
+    ScrollAnimator(ScrollbarClient* client) : m_client(client) { }
+    virtual ~ScrollAnimator() { }
+
+    // Computes a scroll destination for the given parameters.  Returns false if
+    // already at the destination.  Otherwise, starts scrolling towards the
+    // destination and returns true.  Scrolling may be immediate or animated.
+    // The base class implementation always scrolls immediately, never animates.
+    virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
+
+    // Stops any animation in the given direction and updates the ScrollAnimator
+    // with the current scroll position.  This does not cause a callback to the
+    // ScrollbarClient.
+    virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+
+protected:
+    ScrollbarClient* m_client;
+    float m_currentPosX; // We avoid using a FloatPoint in order to reduce
+    float m_currentPosY; // subclass code complexity.
+};
+
+} // namespace WebCore
+#endif
diff --git a/WebCore/platform/ScrollAnimatorWin.cpp b/WebCore/platform/ScrollAnimatorWin.cpp
new file mode 100644 (file)
index 0000000..8b7d0f6
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollAnimatorWin.h"
+
+#include "ScrollbarClient.h"
+#include "ScrollbarTheme.h"
+#include <algorithm>
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+// static
+ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client)
+{
+    return new ScrollAnimatorWin(client);
+}
+
+const double ScrollAnimatorWin::animationTimerDelay = 0.01;
+
+ScrollAnimatorWin::PerAxisData::PerAxisData(ScrollAnimatorWin* parent, float* currentPos)
+    : m_currentPos(currentPos)
+    , m_desiredPos(0)
+    , m_currentVelocity(0)
+    , m_desiredVelocity(0)
+    , m_lastAnimationTime(0)
+    , m_animationTimer(parent, &ScrollAnimatorWin::animationTimerFired)
+{
+}
+
+
+ScrollAnimatorWin::ScrollAnimatorWin(ScrollbarClient* client)
+    : ScrollAnimator(client)
+    , m_horizontalData(this, &m_currentPosX)
+    , m_verticalData(this, &m_currentPosY)
+{
+}
+
+ScrollAnimatorWin::~ScrollAnimatorWin()
+{
+    stopAnimationTimerIfNeeded(&m_horizontalData);
+    stopAnimationTimerIfNeeded(&m_verticalData);
+}
+
+bool ScrollAnimatorWin::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+{
+    // Don't animate jumping to the beginning or end of the document.
+    if (granularity == ScrollByDocument)
+        return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
+
+    // This is an animatable scroll.  Calculate the scroll delta.
+    PerAxisData* data = (orientation == VerticalScrollbar) ? &m_verticalData : &m_horizontalData;
+    float newPos = std::max(std::min(data->m_desiredPos + (step * multiplier), static_cast<float>(m_client->scrollSize(orientation))), 0.0f);
+    if (newPos == data->m_desiredPos)
+        return false;
+    data->m_desiredPos = newPos;
+
+    // Calculate the animation velocity.
+    if (*data->m_currentPos == data->m_desiredPos)
+        return false;
+    bool alreadyAnimating = data->m_animationTimer.isActive();
+    // There are a number of different sources of scroll requests.  We want to
+    // make both keyboard and wheel-generated scroll requests (which can come at
+    // unpredictable rates) and autoscrolling from holding down the mouse button
+    // on a scrollbar part (where the request rate can be obtained from the
+    // scrollbar theme) feel smooth, responsive, and similar.
+    //
+    // When autoscrolling, the scrollbar's autoscroll timer will call us to
+    // increment the desired position by |step| (with |multiplier| == 1) every
+    // ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() seconds.  If we set
+    // the desired velocity to exactly this rate, smooth scrolling will neither
+    // race ahead (and then have to slow down) nor increasingly lag behind, but
+    // will be smooth and synchronized.
+    //
+    // Note that because of the acceleration period, the current position in
+    // this case would lag the desired one by a small, constant amount (see
+    // comments on animateScroll()); the exact amount is given by
+    //   lag = |step| - v(0.5tA + tD)
+    // Where
+    //   v = The steady-state velocity,
+    //       |step| / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay()
+    //   tA = accelerationTime()
+    //   tD = The time we pretend has already passed when starting to scroll,
+    //        |animationTimerDelay|
+    //
+    // This lag provides some buffer against timer jitter so we're less likely
+    // to hit the desired position and stop (and thus have to re-accelerate,
+    // causing a visible hitch) while waiting for the next autoscroll increment.
+    //
+    // Thus, for autoscroll-timer-triggered requests, the ideal steady-state
+    // distance to travel in each time interval is:
+    //   float animationStep = step;
+    // Note that when we're not already animating, this is exactly the same as
+    // the distance to the target position.  We'll return to that in a moment.
+    //
+    // For keyboard and wheel scrolls, we don't know when the next increment
+    // will be requested.  If we set the target velocity based on how far away
+    // from the target position we are, then for keyboard/wheel events that come
+    // faster than the autoscroll delay, we'll asymptotically approach the
+    // velocity needed to stay smoothly in sync with the user's actions; for
+    // events that come slower, we'll scroll one increment and then pause until
+    // the next event fires.
+    float animationStep = abs(newPos - *data->m_currentPos);
+    // If a key is held down (or the wheel continually spun), then once we have
+    // reached a velocity close to the steady-state velocity, we're likely to
+    // hit the desired position at around the same time we'd expect the next
+    // increment to occur -- bad because it leads to hitching as described above
+    // (if autoscroll-based requests didn't result in a small amount of constant
+    // lag).  So if we're called again while already animating, we want to trim
+    // the animationStep slightly to maintain lag like what's described above.
+    // (I say "maintain" since we'll already be lagged due to the acceleration
+    // during the first scroll period.)
+    //
+    // Remember that trimming won't cause us to fall steadily further behind
+    // here, because the further behind we are, the larger the base step value
+    // above.  Given the scrolling algorithm in animateScroll(), the practical
+    // effect will actually be that, assuming a constant trim factor, we'll lag
+    // by a constant amount depending on the rate at which increments occur
+    // compared to the autoscroll timer delay.  The exact lag is given by
+    //   lag = |step| * ((r / k) - 1)
+    // Where
+    //   r = The ratio of the autoscroll repeat delay,
+    //       ScrollbarTheme::nativeTheme()->autoscrollTimerDelay(), to the
+    //       key/wheel repeat delay (i.e. > 1 when keys repeat faster)
+    //   k = The velocity trim constant given below
+    //
+    // We want to choose the trim factor such that for calls that come at the
+    // autoscroll timer rate, we'll wind up with the same lag as in the
+    // "perfect" case described above (or, to put it another way, we'll end up
+    // with |animationStep| == |step| * |multiplier| despite the actual distance
+    // calculated above being larger than that).  This will result in "perfect"
+    // behavior for autoscrolling without having to special-case it.
+    if (alreadyAnimating)
+        animationStep /= (2.0 - ((1.0 / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay()) * (0.5 * accelerationTime() + animationTimerDelay)));
+    // The result of all this is that single keypresses or wheel flicks will
+    // scroll in the same time period as single presses of scrollbar elements;
+    // holding the mouse down on a scrollbar part will scroll as fast as
+    // possible without hitching; and other repeated scroll events will also
+    // scroll with the same time lag as holding down the mouse on a scrollbar
+    // part.
+    data->m_desiredVelocity = animationStep / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay();
+
+    // If we're not already scrolling, start.
+    if (!alreadyAnimating)
+        animateScroll(data);
+    return true;
+}
+
+void ScrollAnimatorWin::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+    PerAxisData* data = (orientation == HorizontalScrollbar) ? &m_horizontalData : &m_verticalData;
+    stopAnimationTimerIfNeeded(data);
+    *data->m_currentPos = pos;
+    data->m_desiredPos = pos;
+    data->m_currentVelocity = 0;
+    data->m_desiredVelocity = 0;
+}
+
+// static
+double ScrollAnimatorWin::accelerationTime()
+{
+    // We elect to use ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() as
+    // the length of time we'll take to accelerate from 0 to our target
+    // velocity.  Choosing a larger value would produce a more pronounced
+    // acceleration effect.
+    return ScrollbarTheme::nativeTheme()->autoscrollTimerDelay();
+}
+
+void ScrollAnimatorWin::animationTimerFired(Timer<ScrollAnimatorWin>* timer)
+{
+    animateScroll((timer == &m_horizontalData.m_animationTimer) ? &m_horizontalData : &m_verticalData);
+}
+
+void ScrollAnimatorWin::stopAnimationTimerIfNeeded(PerAxisData* data)
+{
+    if (data->m_animationTimer.isActive())
+        data->m_animationTimer.stop();
+}
+
+void ScrollAnimatorWin::animateScroll(PerAxisData* data)
+{
+    // Note on smooth scrolling perf versus non-smooth scrolling perf:
+    // The total time to perform a complete scroll is given by
+    //   t = t0 + 0.5tA - tD + tS
+    // Where
+    //   t0 = The time to perform the scroll without smooth scrolling
+    //   tA = The acceleration time,
+    //        ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() (see below)
+    //   tD = |animationTimerDelay|
+    //   tS = A value less than or equal to the time required to perform a
+    //        single scroll increment, i.e. the work done due to calling
+    //        client()->valueChanged() (~0 for simple pages, larger for complex
+    //        pages).
+    //
+    // Because tA and tD are fairly small, the total lag (as users perceive it)
+    // is negligible for simple pages and roughly tS for complex pages.  Without
+    // knowing in advance how large tS is it's hard to do better than this.
+    // Perhaps we could try to remember previous values and forward-compensate.
+
+
+    // We want to update the scroll position based on the time it's been since
+    // our last update.  This may be longer than our ideal time, especially if
+    // the page is complex or the system is slow.
+    //
+    // To avoid feeling laggy, if we've just started smooth scrolling we pretend
+    // we've already accelerated for one ideal interval, so that we'll scroll at
+    // least some distance immediately.
+    double lastScrollInterval = data->m_currentVelocity ? (WTF::currentTime() - data->m_lastAnimationTime) : animationTimerDelay;
+
+    // Figure out how far we've actually traveled and update our current
+    // velocity.
+    float distanceTraveled;
+    if (data->m_currentVelocity < data->m_desiredVelocity) {
+        // We accelerate at a constant rate until we reach the desired velocity.
+        float accelerationRate = data->m_desiredVelocity / accelerationTime();
+
+        // Figure out whether contant acceleration has caused us to reach our
+        // target velocity.
+        float potentialVelocityChange = accelerationRate * lastScrollInterval;
+        float potentialNewVelocity = data->m_currentVelocity + potentialVelocityChange;
+        if (potentialNewVelocity > data->m_desiredVelocity) {
+            // We reached the target velocity at some point between our last
+            // update and now.  The distance traveled can be calculated in two
+            // pieces: the distance traveled while accelerating, and the
+            // distance traveled after reaching the target velocity.
+            float actualVelocityChange = data->m_desiredVelocity - data->m_currentVelocity;
+            float accelerationInterval = actualVelocityChange / accelerationRate;
+            // The distance traveled under constant acceleration is the area
+            // under a line segment with a constant rising slope.  Break this
+            // into a triangular portion atop a rectangular portion and sum.
+            distanceTraveled = ((data->m_currentVelocity + (actualVelocityChange / 2)) * accelerationInterval);
+            // The distance traveled at the target velocity is simply
+            // (target velocity) * (remaining time after accelerating).
+            distanceTraveled += (data->m_desiredVelocity * (lastScrollInterval - accelerationInterval));
+            data->m_currentVelocity = data->m_desiredVelocity;
+        } else {
+            // Constant acceleration through the entire time interval.
+            distanceTraveled = (data->m_currentVelocity + (potentialVelocityChange / 2)) * lastScrollInterval;
+            data->m_currentVelocity = potentialNewVelocity;
+        }
+    } else {
+        // We've already reached the target velocity, so the distance we've
+        // traveled is simply (current velocity) * (elapsed time).
+        distanceTraveled = data->m_currentVelocity * lastScrollInterval;
+        // If our desired velocity has decreased, drop the current velocity too.
+        data->m_currentVelocity = data->m_desiredVelocity;
+    }
+
+    // Now update the scroll position based on the distance traveled.
+    if (distanceTraveled >= abs(data->m_desiredPos - *data->m_currentPos)) {
+        // We've traveled far enough to reach the desired position.  Stop smooth
+        // scrolling.
+        *data->m_currentPos = data->m_desiredPos;
+        data->m_currentVelocity = 0;
+        data->m_desiredVelocity = 0;
+    } else {
+        // Not yet at the target position.  Travel towards it and set up the
+        // next update.
+        if (*data->m_currentPos > data->m_desiredPos)
+            distanceTraveled = -distanceTraveled;
+        *data->m_currentPos += distanceTraveled;
+        data->m_animationTimer.startOneShot(animationTimerDelay);
+        data->m_lastAnimationTime = WTF::currentTime();
+    }
+    m_client->setScrollOffsetFromAnimation(IntPoint(*m_horizontalData.m_currentPos, *m_verticalData.m_currentPos));
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ScrollAnimatorWin.h b/WebCore/platform/ScrollAnimatorWin.h
new file mode 100644 (file)
index 0000000..002a454
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScrollAnimatorWin_h
+#define ScrollAnimatorWin_h
+
+#include "ScrollAnimator.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class ScrollAnimatorWin : public ScrollAnimator {
+public:
+    ScrollAnimatorWin(ScrollbarClient*);
+    virtual ~ScrollAnimatorWin();
+
+    virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
+    virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+
+private:
+    struct PerAxisData {
+        PerAxisData(ScrollAnimatorWin* parent, float* currentPos);
+
+        float* m_currentPos;
+        float m_desiredPos;
+        float m_currentVelocity;
+        float m_desiredVelocity;
+        double m_lastAnimationTime;
+        Timer<ScrollAnimatorWin> m_animationTimer;
+    };
+
+    static double accelerationTime();
+    static const double animationTimerDelay;
+
+    void animationTimerFired(Timer<ScrollAnimatorWin>*);
+    void stopAnimationTimerIfNeeded(PerAxisData*);
+    void animateScroll(PerAxisData*);
+
+    PerAxisData m_horizontalData;
+    PerAxisData m_verticalData;
+};
+
+}
+#endif
index 4c01175..679de83 100644 (file)
@@ -273,6 +273,20 @@ IntPoint ScrollView::maximumScrollPosition() const
     return IntPoint(maximumOffset.width(), maximumOffset.height());
 }
 
+int ScrollView::scrollSize(ScrollbarOrientation orientation) const
+{
+    Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get();
+    return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
+}
+
+void ScrollView::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    if (m_horizontalScrollbar)
+        m_horizontalScrollbar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
+    if (m_verticalScrollbar)
+        m_verticalScrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void ScrollView::valueChanged(Scrollbar* scrollbar)
 {
     // Figure out if we really moved.
@@ -441,7 +455,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
             m_horizontalScrollbar->setSuppressInvalidation(true);
         m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
-        m_horizontalScrollbar->setValue(scroll.width());
+        m_horizontalScrollbar->setValue(scroll.width(), Scrollbar::NotFromScrollAnimator);
         if (m_scrollbarsSuppressed)
             m_horizontalScrollbar->setSuppressInvalidation(false); 
     } 
@@ -463,7 +477,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
             m_verticalScrollbar->setSuppressInvalidation(true);
         m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
         m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
-        m_verticalScrollbar->setValue(scroll.height());
+        m_verticalScrollbar->setValue(scroll.height(), Scrollbar::NotFromScrollAnimator);
         if (m_scrollbarsSuppressed)
             m_verticalScrollbar->setSuppressInvalidation(false);
     }
@@ -673,7 +687,12 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
             if (negative)
                 deltaY = -deltaY;
         }
-        scrollBy(IntSize(-deltaX, -deltaY));
+
+        // Should we fall back on scrollBy() if there is no scrollbar for a non-zero delta?
+        if (deltaY && m_verticalScrollbar)
+            m_verticalScrollbar->scroll(ScrollUp, ScrollByPixel, deltaY);
+        if (deltaX && m_horizontalScrollbar)
+            m_horizontalScrollbar->scroll(ScrollLeft, ScrollByPixel, deltaX);
     }
 }
 
index 940ead0..94fa671 100644 (file)
@@ -58,7 +58,9 @@ class ScrollView : public Widget, public ScrollbarClient {
 public:
     ~ScrollView();
 
-    // ScrollbarClient function. FrameView overrides the others.
+    // ScrollbarClient functions.  FrameView overrides the others.
+    virtual int scrollSize(ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&);
     virtual void valueChanged(Scrollbar*);
     
     // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
index 99b32fd..398584a 100644 (file)
@@ -101,12 +101,12 @@ Scrollbar::~Scrollbar()
     m_theme->unregisterScrollbar(this);
 }
 
-bool Scrollbar::setValue(int v)
+bool Scrollbar::setValue(int v, ScrollSource source)
 {
     v = max(min(v, m_totalSize - m_visibleSize), 0);
     if (value() == v)
         return false; // Our value stayed the same.
-    setCurrentPos(v);
+    setCurrentPos(v, source);
     return true;
 }
 
@@ -154,8 +154,10 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity,
     }
     if (direction == ScrollUp || direction == ScrollLeft)
         multiplier = -multiplier;
+    if (client())
+        return client()->scroll(m_orientation, granularity, step, multiplier);
 
-    return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f));
+    return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f), NotFromScrollAnimator);
 }
 
 void Scrollbar::updateThumb()
@@ -287,11 +289,14 @@ void Scrollbar::moveThumb(int pos)
     else if (delta < 0)
         delta = max(-thumbPos, delta);
     if (delta)
-        setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen));
+        setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen), NotFromScrollAnimator);
 }
 
-bool Scrollbar::setCurrentPos(float pos)
+bool Scrollbar::setCurrentPos(float pos, ScrollSource source)
 {
+    if ((source != FromScrollAnimator) && client())
+        client()->setScrollPositionAndStopAnimation(m_orientation, pos);
+
     if (pos == m_currentPos)
         return false;
 
@@ -336,7 +341,7 @@ bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
 {
     if (m_pressedPart == ThumbPart) {
         if (theme()->shouldSnapBackToDragOrigin(this, evt))
-            setCurrentPos(m_dragOrigin);
+            setCurrentPos(m_dragOrigin, NotFromScrollAnimator);
         else {
             moveThumb(m_orientation == HorizontalScrollbar ? 
                       convertFromContainingWindow(evt.pos()).x() :
index f8ef96d..276bf60 100644 (file)
@@ -42,6 +42,11 @@ class PlatformMouseEvent;
 
 class Scrollbar : public Widget {
 public:
+    enum ScrollSource {
+        FromScrollAnimator,
+        NotFromScrollAnimator,
+    };
+
     virtual ~Scrollbar();
 
     // Must be implemented by platforms that can't simply use the Scrollbar base class.  Right now the only platform that is not using the base class is GTK.
@@ -75,7 +80,7 @@ public:
     virtual void setPressedPart(ScrollbarPart);
 
     void setSteps(int lineStep, int pageStep, int pixelsPerStep = 1);
-    bool setValue(int);
+    bool setValue(int, ScrollSource source);
     void setProportion(int visibleSize, int totalSize);
     void setPressedPos(int p) { m_pressedPos = p; }
 
@@ -167,7 +172,7 @@ protected:
 private:
     virtual bool isScrollbar() const { return true; }
 
-    bool setCurrentPos(float pos);
+    bool setCurrentPos(float pos, ScrollSource source);
 };
 
 }
diff --git a/WebCore/platform/ScrollbarClient.cpp b/WebCore/platform/ScrollbarClient.cpp
new file mode 100644 (file)
index 0000000..2f81a93
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollbarClient.h"
+
+#include "ScrollAnimator.h"
+
+namespace WebCore {
+
+ScrollbarClient::ScrollbarClient()
+    : m_scrollAnimator(ScrollAnimator::create(this))
+{
+}
+
+ScrollbarClient::~ScrollbarClient()
+{
+}
+
+bool ScrollbarClient::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+{
+    return m_scrollAnimator->scroll(orientation, granularity, step, multiplier);
+}
+
+void ScrollbarClient::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+    m_scrollAnimator->setScrollPositionAndStopAnimation(orientation, pos);
+}
+
+} // namespace WebCore
index fa94ecc..ab3b10e 100644 (file)
 #ifndef ScrollbarClient_h
 #define ScrollbarClient_h
 
+#include "IntPoint.h"
 #include "IntRect.h"
 #include "Scrollbar.h"
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
+class ScrollAnimator;
+
 class ScrollbarClient {
 public:
-    virtual ~ScrollbarClient() { }
-    virtual void valueChanged(Scrollbar*) = 0;
+    ScrollbarClient();
+    virtual ~ScrollbarClient();
 
-    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
+    bool scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier);
+    void setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos);
 
+    virtual int scrollSize(ScrollbarOrientation orientation) const = 0;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&) = 0;
+    virtual void valueChanged(Scrollbar*) = 0;
+    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
     virtual bool isActive() const = 0;
-    
     virtual bool scrollbarCornerPresent() const = 0;
 
     virtual void getTickmarks(Vector<IntRect>&) const { }
@@ -52,21 +59,21 @@ public:
     {
         return scrollbar->Widget::convertToContainingView(scrollbarRect);
     }
-    
     virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
     {
         return scrollbar->Widget::convertFromContainingView(parentRect);
     }
-    
     virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
     {
         return scrollbar->Widget::convertToContainingView(scrollbarPoint);
     }
-    
     virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
     {
         return scrollbar->Widget::convertFromContainingView(parentPoint);
     }
+
+private:
+    OwnPtr<ScrollAnimator> m_scrollAnimator;
 };
 
 }
index 6e739ff..c2e24e0 100644 (file)
@@ -108,7 +108,7 @@ void MainFrameScrollbarGtk::updateThumbProportion()
 
 void MainFrameScrollbarGtk::gtkValueChanged(GtkAdjustment*, MainFrameScrollbarGtk* that)
 {
-    that->setValue(static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())));
+    that->setValue(static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())), NotFromScrollAnimator);
 }
 
 void MainFrameScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect)
index 85dc107..a517064 100644 (file)
@@ -76,11 +76,11 @@ bool Scrollbar::contextMenu(const PlatformMouseEvent& event)
         const QPoint pos = convertFromContainingWindow(event.pos());
         moveThumb(horizontal ? pos.x() : pos.y());
     } else if (actionSelected == actScrollTop)
-        setValue(0);
+        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByDocument);
     else if (actionSelected == actScrollBottom)
-        setValue(maximum());
+        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByDocument);
     else if (actionSelected == actPageUp)
-        scroll(horizontal ? ScrollLeft: ScrollUp, ScrollByPage);
+        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByPage);
     else if (actionSelected == actPageDown)
         scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
     else if (actionSelected == actScrollUp)
index 6e22024..5dc43c2 100644 (file)
@@ -664,6 +664,17 @@ void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
         ::ReleaseDC(m_popup, localDC);
 }
 
+int PopupMenuWin::scrollSize(ScrollbarOrientation orientation) const
+{
+    return ((orientation == VerticallScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
+}
+
+void PopupMenuWin::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    if (m_scrollbar)
+        m_scrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void PopupMenuWin::valueChanged(Scrollbar* scrollBar)
 {
     ASSERT(m_scrollbar);
index d4a4255..bfec7aa 100644 (file)
@@ -91,6 +91,8 @@ private:
     void setScrollbarCapturingMouse(bool b) { m_scrollbarCapturingMouse = b; }
 
     // ScrollBarClient
+    virtual int scrollSize(ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&);
     virtual void valueChanged(Scrollbar*);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const { return true; }
index 916d253..63a21cd 100644 (file)
@@ -170,6 +170,17 @@ void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
 }
 
 // Scrolling implementation functions
+int RenderDataGrid::scrollSize(ScrollbarOrientation orientation) const
+{
+    return ((orientation == VerticallScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
+}
+
+void RenderDataGrid::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    if (m_vBar)
+        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void RenderDataGrid::valueChanged(Scrollbar*)
 {
     // FIXME: Implement.
index ce221ea..c4b54df 100644 (file)
@@ -67,6 +67,8 @@ private:
     HTMLDataGridElement* gridElement() const { return static_cast<HTMLDataGridElement*>(node()); }
 
     // ScrollbarClient interface.
+    virtual int scrollSize(ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&);
     virtual void valueChanged(Scrollbar*);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
index cba61a9..1477a23 100644 (file)
@@ -1364,9 +1364,9 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
 
     if (updateScrollbars) {
         if (m_hBar)
-            m_hBar->setValue(scrollXOffset());
+            m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
         if (m_vBar)
-            m_vBar->setValue(m_scrollY);
+            m_vBar->setValue(m_scrollY, Scrollbar::NotFromScrollAnimator);
     }
 
     // Schedule the scroll DOM event.
@@ -1619,6 +1619,20 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
 }
 
+int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
+{
+    Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
+    return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
+}
+
+void RenderLayer::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    if (m_hBar)
+        m_hBar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
+    if (m_vBar)
+        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void RenderLayer::valueChanged(Scrollbar*)
 {
     // Update scroll position from scrollbars.
@@ -2069,7 +2083,7 @@ RenderLayer::updateScrollInfoAfterLayout()
         // so this is needed to keep everything working (see how scrollXOffset()
         // differs from scrollYOffset() to get an idea of why the horizontal and
         // vertical scrollbars need to be treated differently).
-        m_hBar->setValue(scrollXOffset());
+        m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
     }
     if (m_vBar) {
         int clientHeight = box->clientHeight();
index 624bad2..82edab2 100644 (file)
@@ -518,6 +518,8 @@ private:
     bool shouldBeNormalFlowOnly() const; 
 
     // ScrollBarClient interface
+    virtual int scrollSize(ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&);
     virtual void valueChanged(Scrollbar*);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
index 2ecc2d0..aa31b6c 100644 (file)
@@ -500,7 +500,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
 
     m_indexOffset = newOffset;
     if (m_vBar)
-        m_vBar->setValue(m_indexOffset);
+        m_vBar->setValue(m_indexOffset, Scrollbar::NotFromScrollAnimator);
 
     return true;
 }
@@ -523,6 +523,17 @@ void RenderListBox::valueChanged(unsigned listIndex)
     element->dispatchFormControlChangeEvent();
 }
 
+int RenderListBox::scrollSize(ScrollbarOrientation orientation) const
+{
+    return ((orientation == VerticalScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
+}
+
+void RenderListBox::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+    if (m_vBar)
+        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void RenderListBox::valueChanged(Scrollbar*)
 {
     int newOffset = m_vBar->value();
@@ -578,7 +589,7 @@ void RenderListBox::setScrollTop(int newTop)
         return;
     m_indexOffset = index;
     if (m_vBar)
-        m_vBar->setValue(index);
+        m_vBar->setValue(index, Scrollbar::NotFromScrollAnimator);
 }
 
 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
index 36cb87a..dcee739 100644 (file)
@@ -96,6 +96,8 @@ private:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
     // ScrollbarClient interface.
+    virtual int scrollSize(ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const IntPoint&);
     virtual void valueChanged(Scrollbar*);
     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
     virtual bool isActive() const;
index 567eb75..4e8f366 100644 (file)
@@ -1,3 +1,21 @@
+2010-09-08  Peter Kasting  <pkasting@google.com>
+
+        Reviewed by David Hyatt.
+
+        Add smooth scrolling framework, and a Windows implementation.
+        https://bugs.webkit.org/show_bug.cgi?id=32356
+
+        * src/WebScrollbarImpl.cpp: Plumb new ScrollbarClient functions.  Allow wheel scrolls to be animated.
+        (WebKit::WebScrollbarImpl::setLocation):
+        (WebKit::WebScrollbarImpl::setValue):
+        (WebKit::WebScrollbarImpl::scroll):
+        (WebKit::WebScrollbarImpl::onMouseWheel):
+        (WebKit::WebScrollbarImpl::onKeyDown):
+        (WebKit::WebScrollbarImpl::setScrollOffsetFromAnimation):
+        * src/WebScrollbarImpl.h: Plumb new ScrollbarClient functions.
+        * src/win/WebInputEventFactory.cpp: Update comments now that we have smooth scrolling.
+        (WebKit::WebInputEventFactory::mouseWheelEvent):
+
 2010-09-08  Yury Semikhatsky  <yurys@chromium.org>
 
         Reviewed by Joseph Pecoraro.
index c0131cb..8b9e287 100644 (file)
@@ -94,7 +94,7 @@ int WebScrollbarImpl::value() const
 
 void WebScrollbarImpl::setValue(int position)
 {
-    m_scrollbar->setValue(position);
+    m_scrollbar->setValue(position, Scrollbar::NotFromScrollAnimator);
 }
 
 void WebScrollbarImpl::setDocumentSize(int size)
@@ -218,7 +218,7 @@ bool WebScrollbarImpl::onMouseWheel(const WebInputEvent& event)
                 if (negative)
                     delta *= -1;
             }
-            m_scrollbar->setValue(m_scrollbar->value() - delta);
+            m_scrollbar->scroll((m_scrollbar->orientation() == HorizontalScrollbar) ? WebCore::ScrollLeft : WebCore::ScrollUp, WebCore::ScrollByPixel, delta);
             return true;
         }
 
@@ -262,6 +262,16 @@ bool WebScrollbarImpl::onKeyDown(const WebInputEvent& event)
     return false;
 }
 
+int WebScrollbarImpl::scrollSize(WebCore::ScrollbarOrientation orientation) const
+{
+    return (orientation == m_scrollbar->orientation()) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
+}
+
+void WebScrollbarImpl::setScrollOffsetFromAnimation(const WebCore::IntPoint& offset)
+{
+    m_scrollbar->setValue((m_scrollbar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(), Scrollbar::FromScrollAnimator);
+}
+
 void WebScrollbarImpl::valueChanged(WebCore::Scrollbar*)
 {
     m_client->valueChanged(this);
index a041ccc..5512867 100644 (file)
@@ -58,6 +58,8 @@ public:
     virtual bool handleInputEvent(const WebInputEvent&);
 
     // WebCore::ScrollbarClient methods
+    virtual int scrollSize(WebCore::ScrollbarOrientation orientation) const;
+    virtual void setScrollOffsetFromAnimation(const WebCore::IntPoint&);
     virtual void valueChanged(WebCore::Scrollbar*);
     virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&);
     virtual bool isActive() const;
index 4d83f22..d1d5869 100644 (file)
@@ -403,6 +403,9 @@ WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(HWND hwnd, UINT message
     // smooth scrolling while Firefox doesn't, so it can get away with somewhat
     // larger scroll values without feeling as jerky.  Here we use 100 px per
     // three lines (the default scroll amount is three lines per wheel tick).
+    // Even though we have smooth scrolling, we don't make this as large as IE
+    // because subjectively IE feels like it scrolls farther than you want while
+    // reading articles.
     static const float scrollbarPixelsPerLine = 100.0f / 3.0f;
     wheelDelta /= WHEEL_DELTA;
     float scrollDelta = wheelDelta;
index 81eabfc..464b4a0 100644 (file)
@@ -929,7 +929,7 @@ void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value)
             value = 0;
         else if (value > scrollBarMaximum(orientation))
             value = scrollBarMaximum(orientation);
-        sb->setValue(value);
+        sb->setValue(value, Scrollbar::NotFromScrollAnimator);
     }
 }
 
index c44e532..6ad4c61 100644 (file)
@@ -1,3 +1,13 @@
+2010-09-08  Peter Kasting  <pkasting@google.com>
+
+        Reviewed by David Hyatt.
+
+        Add smooth scrolling framework, and a Windows implementation.
+        https://bugs.webkit.org/show_bug.cgi?id=32356
+
+        * Api/qwebframe.cpp:
+        (QWebFrame::setScrollBarValue):
+
 2010-09-06  Diego Gonzalez  <diegohcg@webkit.org>
 
         Reviewed by Antonio Gomes.
diff --git a/wscript b/wscript
index 3a9302a..54d207f 100644 (file)
--- a/wscript
+++ b/wscript
@@ -68,6 +68,8 @@ if build_port == "wx":
         webcore_sources['wx-win'] = [
                'WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp',
                'WebCore/platform/graphics/win/TransformationMatrixWin.cpp',
+               'WebCore/platform/win/ScrollAnimatorWin.cpp',
+               'WebCore/platform/win/ScrollAnimatorWin.h',
                # wxTimer on Windows has a bug that causes it to eat crashes in callbacks
                # so we need to use the Win port's implementation until the wx bug fix is
                # widely available (it was fixed in 2.8.10).