Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Forward scroll events up the responder chain.

The default implementation of a responder is to forward scroll events up
the chain.

If a TUIScrollView cannot scroll in the given direction, forward it up
the chain.

Accomplish the direction detection by inspecting the direction of the
first NSEventPhaseChanged.

Include an example of nested scroll views within the example project.
  • Loading branch information...
commit e33585df1754bb81b9ba4723135959d17d26ff3e 1 parent a555cd8
Ben Sandofsky authored
View
3  ExampleProject/ConcordeExample/ExampleAppDelegate.h
@@ -21,9 +21,10 @@
{
NSWindow * tableViewWindow;
NSWindow * scrollViewWindow;
+ NSWindow * nestedScrollViewWindow;
}
-(IBAction)showTableViewExampleWindow:(id)sender;
-(IBAction)showScrollViewExampleWindow:(id)sender;
-
+-(IBAction)showNestedScrollViews:(id)sender;
@end
View
25 ExampleProject/ConcordeExample/ExampleAppDelegate.m
@@ -17,6 +17,7 @@
#import "ExampleAppDelegate.h"
#import "ExampleView.h"
#import "ExampleScrollView.h"
+#import "ExampleNestedScrollView.h"
@implementation ExampleAppDelegate
@@ -60,7 +61,22 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
ExampleScrollView *scrollExample = [[ExampleScrollView alloc] initWithFrame:b];
tuiScrollViewContainer.rootView = scrollExample;
[scrollExample release];
+
+ /** Scroll View */
+ nestedScrollViewWindow = [[NSWindow alloc] initWithContentRect:b styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES];
+ [nestedScrollViewWindow setReleasedWhenClosed:FALSE];
+ [nestedScrollViewWindow setMinSize:NSMakeSize(300, 250)];
+ [nestedScrollViewWindow setFrameTopLeftPoint:[scrollViewWindow cascadeTopLeftFromPoint:CGPointMake(scrollViewWindow.frame.origin.x, scrollViewWindow.frame.origin.y + scrollViewWindow.frame.size.height)]];
+ /* TUINSView is the bridge between the standard AppKit NSView-based heirarchy and the TUIView-based heirarchy */
+ TUINSView *nestedScrollViewContainer = [[TUINSView alloc] initWithFrame:b];
+ [nestedScrollViewWindow setContentView:nestedScrollViewContainer];
+ [nestedScrollViewContainer release];
+
+ ExampleNestedScrollView *nestedScrollView = [[ExampleNestedScrollView alloc] initWithFrame:b];
+ nestedScrollViewContainer.rootView = nestedScrollView;
+ [nestedScrollView release];
+
[self showTableViewExampleWindow:nil];
}
@@ -79,4 +95,13 @@ -(IBAction)showScrollViewExampleWindow:(id)sender {
[scrollViewWindow makeKeyAndOrderFront:sender];
}
+/**
+ * @brief show the nested sscroll view example
+ */
+
+-(IBAction)showNestedScrollViews:(id)sender
+{
+ [nestedScrollViewWindow makeKeyAndOrderFront:sender];
+}
+
@end
View
21 ExampleProject/ConcordeExample/ExampleNestedScrollView.h
@@ -0,0 +1,21 @@
+/*
+ Copyright 2011 Twitter, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this work except in compliance with the License.
+ You may obtain a copy of the License in the LICENSE file, or at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#import "TUIKit.h"
+
+@interface ExampleNestedScrollView : TUIView
+
+@end
View
55 ExampleProject/ConcordeExample/ExampleNestedScrollView.m
@@ -0,0 +1,55 @@
+/*
+ Copyright 2011 Twitter, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this work except in compliance with the License.
+ You may obtain a copy of the License in the LICENSE file, or at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#import "ExampleNestedScrollView.h"
+
+@interface ExampleNestedScrollView (){
+ TUIScrollView *_outerScrollView;
+ TUIScrollView *_innerScrollView;
+}
+@end
+
+@implementation ExampleNestedScrollView
+- (id)initWithFrame:(CGRect)frame
+{
+ if((self = [super initWithFrame:frame])) {
+ _outerScrollView = [[TUIScrollView alloc] initWithFrame:frame];
+ _outerScrollView.autoresizingMask = TUIViewAutoresizingFlexibleSize;
+ [self addSubview:_outerScrollView];
+ [_outerScrollView release];
+ _outerScrollView.backgroundColor = [TUIColor whiteColor];
+ _outerScrollView.contentSize = CGSizeMake(frame.size.width, 800);
+
+ _innerScrollView = [[TUIScrollView alloc] initWithFrame:CGRectMake(0, 200, frame.size.width, 300)];
+ _innerScrollView.backgroundColor = [TUIColor greenColor];
+ _innerScrollView.autoresizingMask = TUIViewAutoresizingFlexibleWidth;
+ _innerScrollView.contentSize = CGSizeMake(600, 220);
+
+ int x = 10;
+ for (int i = 0; i < 3; i++) {
+ TUIView *v = [[TUIView alloc] initWithFrame:CGRectMake(x, 10, 100, 100)];
+ v.backgroundColor = [TUIColor blackColor];
+ [_innerScrollView addSubview:v];
+ [v release];
+ x += 110;
+ }
+
+ [_outerScrollView addSubview:_innerScrollView];
+ [_innerScrollView release];
+ }
+ return self;
+}
+@end
View
44 ExampleProject/ConcordeExample/en.lproj/MainMenu.xib
@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1070</int>
- <string key="IBDocument.SystemVersion">11B26</string>
- <string key="IBDocument.InterfaceBuilderVersion">1934</string>
- <string key="IBDocument.AppKitVersion">1138</string>
- <string key="IBDocument.HIToolboxVersion">566.00</string>
+ <string key="IBDocument.SystemVersion">11C74</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1938</string>
+ <string key="IBDocument.AppKitVersion">1138.23</string>
+ <string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">1934</string>
+ <string key="NS.object.0">1938</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1288,6 +1288,15 @@
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
+ <object class="NSMenuItem" id="143285636">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Nested Scroll View Example</string>
+ <string key="NSKeyEquiv">3</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
<object class="NSMenuItem" id="193357256">
<reference key="NSMenu" ref="835318025"/>
<bool key="NSIsDisabled">YES</bool>
@@ -2037,6 +2046,14 @@
</object>
<int key="connectionID">537</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showNestedScrollViews:</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="143285636"/>
+ </object>
+ <int key="connectionID">540</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2458,6 +2475,7 @@
<reference ref="416175109"/>
<reference ref="441024329"/>
<reference ref="193357256"/>
+ <reference ref="143285636"/>
</object>
<reference key="parent" ref="713487014"/>
</object>
@@ -3084,6 +3102,11 @@
<reference key="object" ref="193357256"/>
<reference key="parent" ref="835318025"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">538</int>
+ <reference key="object" ref="143285636"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -3228,6 +3251,7 @@
<string>533.IBPluginDependency</string>
<string>534.IBPluginDependency</string>
<string>535.IBPluginDependency</string>
+ <string>538.IBPluginDependency</string>
<string>56.IBPluginDependency</string>
<string>57.IBPluginDependency</string>
<string>58.IBPluginDependency</string>
@@ -3399,6 +3423,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -3413,7 +3438,7 @@
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
- <int key="maxID">537</int>
+ <int key="maxID">540</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -3425,6 +3450,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>showNestedScrollViews:</string>
<string>showScrollViewExampleWindow:</string>
<string>showTableViewExampleWindow:</string>
</object>
@@ -3432,18 +3458,24 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
+ <string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>showNestedScrollViews:</string>
<string>showScrollViewExampleWindow:</string>
<string>showTableViewExampleWindow:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
+ <string key="name">showNestedScrollViews:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
<string key="name">showScrollViewExampleWindow:</string>
<string key="candidateClassName">id</string>
</object>
View
6 ExampleProject/Example.xcodeproj/project.pbxproj
@@ -66,6 +66,7 @@
5ED56727139DC35100031CDF /* TUIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5ED566F2139DC35100031CDF /* TUIView.m */; };
5ED56728139DC35100031CDF /* TUIViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5ED566F4139DC35100031CDF /* TUIViewController.m */; };
5ED56736139DC35800031CDF /* CoreText+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5ED56732139DC35800031CDF /* CoreText+Additions.m */; };
+ B53F95891497C077006118D2 /* ExampleNestedScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = B53F95881497C077006118D2 /* ExampleNestedScrollView.m */; };
D3502AAE13EA0FE4007C5CA7 /* TUITableView+Cell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3502AAD13EA0FE4007C5CA7 /* TUITableView+Cell.m */; };
D3CE671313C6646B00D47B2D /* ExampleSectionHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3CE671213C6646B00D47B2D /* ExampleSectionHeaderView.m */; };
D3EC0C491432325A003C162C /* ExampleScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EC0C471432325A003C162C /* ExampleScrollView.m */; };
@@ -191,6 +192,8 @@
5ED566F5139DC35100031CDF /* TUIViewNSViewContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUIViewNSViewContainer.h; sourceTree = "<group>"; };
5ED56731139DC35800031CDF /* CoreText+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "CoreText+Additions.h"; path = "../Support/CoreText+Additions.h"; sourceTree = "<group>"; };
5ED56732139DC35800031CDF /* CoreText+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "CoreText+Additions.m"; path = "../Support/CoreText+Additions.m"; sourceTree = "<group>"; };
+ B53F95871497C077006118D2 /* ExampleNestedScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleNestedScrollView.h; sourceTree = "<group>"; };
+ B53F95881497C077006118D2 /* ExampleNestedScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleNestedScrollView.m; sourceTree = "<group>"; };
D3502AAC13EA0FE4007C5CA7 /* TUITableView+Cell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TUITableView+Cell.h"; sourceTree = "<group>"; };
D3502AAD13EA0FE4007C5CA7 /* TUITableView+Cell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TUITableView+Cell.m"; sourceTree = "<group>"; };
D3CE671113C6646B00D47B2D /* ExampleSectionHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleSectionHeaderView.h; sourceTree = "<group>"; };
@@ -285,6 +288,8 @@
5ED56695139DC35100031CDF /* TUIKit */,
5ED56689139DC30300031CDF /* ExampleAppDelegate.h */,
5ED5668A139DC30300031CDF /* ExampleAppDelegate.m */,
+ B53F95871497C077006118D2 /* ExampleNestedScrollView.h */,
+ B53F95881497C077006118D2 /* ExampleNestedScrollView.m */,
5C55D83213A667A0000ED768 /* ExampleView.h */,
5C55D83313A667A0000ED768 /* ExampleView.m */,
D3EC0C461432325A003C162C /* ExampleScrollView.h */,
@@ -550,6 +555,7 @@
D3FA4CBE13F85BC100860379 /* TUINSView+Accessibility.m in Sources */,
D3FA4CBF13F85BC100860379 /* TUIView+Accessibility.m in Sources */,
D3EC0C491432325A003C162C /* ExampleScrollView.m in Sources */,
+ B53F95891497C077006118D2 /* ExampleNestedScrollView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
7 lib/UIKit/TUIResponder.m
@@ -48,4 +48,11 @@ - (TUIResponder *)initialFirstResponder
return self;
}
+- (void)scrollWheel:(NSEvent *)event
+{
+ if([[self nextResponder] respondsToSelector:@selector(scrollWheel:)]){
+ [[self nextResponder] scrollWheel:event];
+ }
+}
+
@end
View
2  lib/UIKit/TUIScrollView.h
@@ -144,6 +144,8 @@ typedef enum {
unsigned int delegateScrollViewDidShowScrollIndicator:1;
unsigned int delegateScrollViewWillHideScrollIndicator:1;
unsigned int delegateScrollViewDidHideScrollIndicator:1;
+ unsigned int inspectNextScrollDirection:1;
+ unsigned int forwardScrollsForPhase:1;
} _scrollViewFlags;
}
View
41 lib/UIKit/TUIScrollView.m
@@ -49,6 +49,7 @@ - (void)_updateScrollKnobs;
- (void)_updateScrollKnobsAnimated:(BOOL)animated;
- (void)_updateBounce;
- (void)_startTimer:(int)scrollMode;
+- (BOOL)_forwardScrollEvent:(NSEvent *)event;
@end
@@ -973,7 +974,6 @@ - (void)_startThrow
- (void)endGestureWithEvent:(NSEvent *)event
{
-
if(_scrollViewFlags.delegateScrollViewDidEndDragging){
[_delegate scrollViewDidEndDragging:self];
}
@@ -988,9 +988,46 @@ - (void)endGestureWithEvent:(NSEvent *)event
}
+// Inspect the scroll direction on gesture. If it is perpendicular
+// to the scrollview, forward it up the responder chain.
+- (BOOL)_forwardScrollEvent:(NSEvent *)event
+{
+ if (!self.scrollEnabled) {
+ [[self superview] scrollWheel:event];
+ return YES;
+ }
+
+ if (!AtLeastLion) {
+ return NO;
+ }
+
+ // Need to see the first delta to determine the direction
+ if ([event phase] == NSEventPhaseBegan) {
+ _scrollViewFlags.forwardScrollsForPhase = NO;
+ _scrollViewFlags.inspectNextScrollDirection = YES;
+ } else if (_scrollViewFlags.inspectNextScrollDirection && [event phase] == NSEventPhaseChanged){
+ _scrollViewFlags.inspectNextScrollDirection = NO;
+ // Horizontal
+ if (fabs([event scrollingDeltaX]) > fabs([event scrollingDeltaY])) {
+ if (self.contentSize.width <= self.frame.size.width) {
+ _scrollViewFlags.forwardScrollsForPhase = YES;
+ }
+ } else if (fabs([event scrollingDeltaX]) < fabs([event scrollingDeltaY])) { // Vertical
+ if (self.contentSize.height <= self.frame.size.height) {
+ _scrollViewFlags.forwardScrollsForPhase = YES;
+ }
+ }
+ }
+
+ if (_scrollViewFlags.forwardScrollsForPhase) {
+ [[self superview] scrollWheel:event];
+ }
+ return _scrollViewFlags.forwardScrollsForPhase;
+}
+
- (void)scrollWheel:(NSEvent *)event
{
- if(self.scrollEnabled)
+ if(![self _forwardScrollEvent:event])
{
int phase = ScrollPhaseNormal;
View
2  lib/UIKit/TUIView+Event.m
@@ -164,7 +164,7 @@ - (BOOL)didDrag
- (void)scrollWheel:(NSEvent *)event
{
- [self.superview scrollWheel:event];
+ [self.superview scrollWheel:event];
}
- (void)beginGestureWithEvent:(NSEvent *)event
Please sign in to comment.
Something went wrong with that request. Please try again.