11 Commits

Author SHA1 Message Date
Alex Rozanski 2eb6414e6b Bump project to 2.0.5 2014-06-07 14:45:37 -04:00
Alex Rozanski 2550dce3b7 Fix #43: sourceListDeleteKeyPressedOnRows: called twice.
This issue was being caused by the fact that the overridden
-setDelegate: method on PXSourceListDelegateDataSourceProxy doesn't
correctly remove the old delegate as observing the PXSourceList
notifications.

Setting the same delegate twice will cause this issue to
occur.
2014-06-07 14:39:44 -04:00
Alex Rozanski c62b8b2c92 Bump project to 2.0.4. 2014-05-11 13:17:39 -04:00
Alex Rozanski 67772622cf Remove unused badgeMargin constant. 2014-05-11 13:12:42 -04:00
Alex Rozanski a555035042 Merge pull request #41 from CrazyCatcher/master
fix a Zeroing Weak References problem
2014-05-11 12:59:55 -04:00
crazycatcher 0129de341e fix a Zeroing Weak References problem 2014-05-06 20:12:51 +08:00
Alex Rozanski 7a82f63e9b Add Release Notes for 2.0.3. 2014-03-25 21:41:47 +00:00
Alex Rozanski b215e263ef Bump project to 2.0.3. 2014-03-25 21:41:41 +00:00
Alex Rozanski 5ce29c98c9 Fix issue in view-based source list example.
This fixes an issue where items created with the add button couldn't be
dragged.
2014-03-25 21:37:06 +00:00
Alex Rozanski 7df260c6f7 Fix #40: Editing titles on cell based source list causes exception.
The cause of this bug was returning YES in
-[PXSourceListDelegateDataSourceProxy respondsToSelector:] for the
NSControl delegate methods -controlTextDidEndEditing:,
-controlTextDidBeginEditing: and -controlTextDidChange: when they were
called on the proxy because NSOutlineView implements them internally.
However we weren't returning a method signature for them in -methodSignatureForSelector:
which was throwing an exception.

This fix has two components:
- We only allow forwarding of NSOutlineView(Delegate|DataSource) methods
  to the source list PXSourceListDelegateDataSourceProxy (which
  was the original intention). If PXSourceList returns YES for
  -respondsToSelector: we ignore it if the method is not from one of
  these two protocols.
- The NSControl delegate methods have been added to the fast-path
  forwarding delegate methods array in
  PXSourceListDelegateDataSourceProxy (the array which contains method
  names which can be forwarded to the source list's delegate as-is, without
  modifying the selector or arguments).

These fix the underlying cause of the exception and implement
the missing behaviour of allowing invocation of these NSControl methods
on the source list's delegate.
2014-03-25 21:29:31 +00:00
Alex Rozanski 8407bc98bb Remove unnecessary computation in -[PXSourceListDelegateDataSourceProxy methodSignatureForSelector:].
Fast-path delegate and data source methods (those whose method
signature doesn't need modification) don't need to be checked in
-methodSignatureForSelector: because they are handled in
-forwardingTargetForSelector: which bypasses the
-methodSignatureForSelector:/forwardInvocation: path.
2014-03-25 21:08:20 +00:00
9 changed files with 50 additions and 20 deletions
+6 -2
View File
@@ -116,7 +116,10 @@ static NSString * const draggingType = @"SourceListExampleDraggingType";
NSImage *albumImage = [NSImage imageNamed:@"album"];
[albumImage setTemplate:YES];
PXSourceListItem *newItem = [PXSourceListItem itemWithTitle:@"New Album" identifier:nil icon:albumImage];
PhotoCollection *collection = [PhotoCollection collectionWithTitle:@"New Album" identifier:nil type:PhotoCollectionTypeUserCreated];
[self.modelObjects addObject:collection];
PXSourceListItem *newItem = [PXSourceListItem itemWithRepresentedObject:collection icon:albumImage];
[self.albumsItem addChildItem:newItem];
NSUInteger childIndex = [[self.albumsItem children] indexOfObject:newItem];
@@ -132,11 +135,12 @@ static NSString * const draggingType = @"SourceListExampleDraggingType";
PXSourceListItem *selectedItem = [self.sourceList itemAtRow:self.sourceList.selectedRow];
PXSourceListItem *parentItem = self.albumsItem;
[self.sourceList removeItemsAtIndexes:[NSIndexSet indexSetWithIndex:[parentItem.children indexOfObject:selectedItem]]
inParent:parentItem
withAnimation:NSTableViewAnimationSlideUp];
[self.modelObjects removeObject:selectedItem.representedObject];
// Only 'album' items can be deleted.
[parentItem removeChildItem:selectedItem];
}
+2 -2
View File
@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.2</string>
<string>2.0.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2.0.2</string>
<string>2.0.5</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2009-14 Alex Rozanski and other contributors. All rights reserved.</string>
<key>NSPrincipalClass</key>
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PXSourceList'
s.version = '2.0.2'
s.version = '2.0.5'
s.author = { 'Alex Rozanski' => 'alex@rozanski.me' }
s.license = 'BSD'
s.homepage = 'https://github.com/Perspx/PXSourceList'
@@ -23,6 +23,6 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.7'
s.public_header_files = 'PXSourceList/*.h'
s.source = { :git => 'https://github.com/Perspx/PXSourceList.git', :tag => '2.0.2' }
s.source = { :git => 'https://github.com/Perspx/PXSourceList.git', :tag => '2.0.5' }
s.source_files = 'PXSourceList/**/*.{h,m}'
end
@@ -13,8 +13,8 @@
@interface PXSourceListDelegateDataSourceProxy : NSProxy <NSOutlineViewDelegate, NSOutlineViewDataSource, PXSourceListDelegate, PXSourceListDataSource>
@property (weak, nonatomic) PXSourceList *sourceList;
@property (weak, nonatomic) id <PXSourceListDelegate> delegate;
@property (weak, nonatomic) id <PXSourceListDataSource> dataSource;
@property (unsafe_unretained, nonatomic) id <PXSourceListDelegate> delegate;
@property (unsafe_unretained, nonatomic) id <PXSourceListDataSource> dataSource;
- (id)initWithSourceList:(PXSourceList *)sourceList;
@@ -36,7 +36,7 @@ static NSArray * __fastPathForwardingDataSourceMethods = nil;
{
__outlineViewDelegateMethods = px_methodNamesForProtocol(@protocol(NSOutlineViewDelegate));
__outlineViewDataSourceMethods = px_methodNamesForProtocol(@protocol(NSOutlineViewDataSource));
__fastPathForwardingDelegateMethods = px_methodNamesForProtocol(@protocol(PXSourceListDelegate));
__fastPathForwardingDelegateMethods = [self fastPathForwardingDelegateMethods];
__fastPathForwardingDataSourceMethods = px_methodNamesForProtocol(@protocol(PXSourceListDataSource));
__requiredOutlineViewDataSourceMethods = @[NSStringFromSelector(@selector(outlineView:numberOfChildrenOfItem:)),
@@ -70,7 +70,7 @@ static NSArray * __fastPathForwardingDataSourceMethods = nil;
- (void)setDelegate:(id<PXSourceListDelegate>)delegate
{
if (self.delegate)
[[NSNotificationCenter defaultCenter] removeObserver:self.delegate name:nil object:self];
[[NSNotificationCenter defaultCenter] removeObserver:self.delegate name:nil object:self.sourceList];
_delegate = delegate;
@@ -100,11 +100,12 @@ static NSArray * __fastPathForwardingDataSourceMethods = nil;
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ([self.sourceList respondsToSelector:aSelector])
return YES;
NSString *methodName = NSStringFromSelector(aSelector);
// Only let the source list override NSOutlineView delegate and data source methods.
if ([self.sourceList respondsToSelector:aSelector] && ([__outlineViewDataSourceMethods containsObject:methodName] || [__outlineViewDelegateMethods containsObject:methodName]))
return YES;
if ([__requiredOutlineViewDataSourceMethods containsObject:methodName])
return YES;
@@ -127,17 +128,14 @@ static NSArray * __fastPathForwardingDataSourceMethods = nil;
return class_conformsToProtocol(object_getClass(self), protocol);
}
// Fast-path delegate and data source methods aren't handled here; they are taken care of in -forwardingTargetForSelector:.
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSString *methodName = NSStringFromSelector(aSelector);
struct objc_method_description description = {NULL, NULL};
if ([__fastPathForwardingDelegateMethods containsObject:methodName])
description = px_methodDescriptionForProtocolMethod(@protocol(PXSourceListDelegate), aSelector);
else if ([__fastPathForwardingDataSourceMethods containsObject:methodName])
description = px_methodDescriptionForProtocolMethod(@protocol(PXSourceListDataSource), aSelector);
else if ([__outlineViewDelegateMethods containsObject:methodName])
if ([__outlineViewDelegateMethods containsObject:methodName])
description = px_methodDescriptionForProtocolMethod(@protocol(NSOutlineViewDelegate), aSelector);
else if ([__outlineViewDataSourceMethods containsObject:methodName])
description = px_methodDescriptionForProtocolMethod(@protocol(NSOutlineViewDataSource), aSelector);
@@ -397,6 +395,18 @@ static NSArray * __fastPathForwardingDataSourceMethods = nil;
return YES;
}
+ (NSArray *)fastPathForwardingDelegateMethods
{
NSMutableArray *methods = [px_methodNamesForProtocol(@protocol(PXSourceListDelegate)) mutableCopy];
// Add the NSControl delegate methods manually (unfortunately these aren't part of a formal protocol).
[methods addObject:px_methodNameForSelector(@selector(controlTextDidEndEditing:))];
[methods addObject:px_methodNameForSelector(@selector(controlTextDidBeginEditing:))];
[methods addObject:px_methodNameForSelector(@selector(controlTextDidChange:))];
return methods;
}
#pragma mark - Notifications
- (void)registerDelegateToReceiveNotification:(NSString*)notification withSelector:(SEL)selector
@@ -16,5 +16,6 @@ extern NSString * const px_protocolIsRequiredMethodKey;
NSArray *px_allProtocolMethods(Protocol *protocol);
NSArray *px_methodNamesForProtocol(Protocol *protocol);
id px_methodNameForSelector(SEL selector);
struct objc_method_description px_methodDescriptionForProtocolMethod(Protocol *protocol, SEL selector);
@@ -26,7 +26,7 @@ NSArray *px_allProtocolMethods(Protocol *protocol)
for (unsigned int j = 0; j < numberOfMethodDescriptions; ++j) {
struct objc_method_description methodDescription = methodDescriptions[j];
[methodList addObject:@{px_protocolMethodNameKey: NSStringFromSelector(methodDescription.name),
[methodList addObject:@{px_protocolMethodNameKey: px_methodNameForSelector(methodDescription.name),
px_protocolMethodArgumentTypesKey: [NSString stringWithUTF8String:methodDescription.types],
px_protocolIsRequiredMethodKey: @(isRequiredMethod)}];
}
@@ -47,6 +47,11 @@ NSArray *px_methodNamesForProtocol(Protocol *protocol)
return methodNames;
}
id px_methodNameForSelector(SEL selector)
{
return NSStringFromSelector(selector);
}
struct objc_method_description px_methodDescriptionForProtocolMethod(Protocol *protocol, SEL selector)
{
struct objc_method_description description = {NULL, NULL};
-1
View File
@@ -15,7 +15,6 @@
//Layout constants
static const CGFloat minBadgeWidth = 22.0; // The minimum badge width for each item (default 22.0).
static const CGFloat badgeHeight = 14.0; // The badge height for each item (default 14.0).
static const CGFloat badgeMargin = 5.0; // The spacing between the badge and the cell for that row.
static const CGFloat rowRightMargin = 5.0; // The spacing between the right edge of the badge and the edge of the table column.
static const CGFloat iconSpacing = 2.0; // The spacing between the icon and it's adjacent cell.
static const CGFloat disclosureTriangleSpace = 18.0; // The indentation reserved for disclosure triangles for non-group items.
+11
View File
@@ -1,5 +1,16 @@
# PXSourceList Release Notes
## 2.0.5
- Fix #43: sourceListDeleteKeyPressedOnRows: called twice. This was caused by an issue where PXSourceList was incorrectly removing the old delegate as an observer of PXSourceList notifications in -setDelegate:.
## 2.0.4
- PR #41: fix a Zeroing Weak References problem. This fixes an issue where using an `NSWindow`, `NSWindowController` or `NSViewController` as a PXSourceList delegate or dataSource would cause problems on 10.7 because prior to 10.8, these classes could not be referenced by zeroing weak references.
- Remove unused `badgeMargin` constant from PXSourceList.m.
## 2.0.3
- Fix #40: Editing titles on cell based source list causes exception.
- Fix issue in view-based source list example where items created with the add button couldn't be dragged.
## 2.0.2
- Fix #39: Badges not drawn correctly when Source List row is selected.