Skip to content

Commit 1c673bd

Browse files
committed
add close delegate
1 parent ba950df commit 1c673bd

5 files changed

+132
-129
lines changed

BFColorPickerPopover.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |spec|
22
spec.name = 'BFColorPickerPopover'
3-
spec.version = '1.0.1'
3+
spec.version = '1.0.2'
44
spec.authors = {'Balázs Faludi' => '[email protected]'}
55
spec.homepage = 'https://github.com/DrummerB/BFColorPickerPopover'
66
spec.screenshot = 'http://i.imgur.com/Qm38i.png'

BFColorPickerPopover/BFColorPickerPopover.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@
3232

3333
#define kBFColorPickerPopoverMinimumDragDistance 50.0f
3434

35-
@interface BFColorPickerPopover : NSPopover
35+
@interface BFColorPickerPopover : NSPopover<NSPopoverDelegate>
3636

3737
@property (nonatomic) id target;
3838
@property (nonatomic) SEL action;
3939
@property (nonatomic, weak) NSColor *color;
40+
@property (nonatomic) NSObject* onCloseDelegate;
4041

4142
+ (BFColorPickerPopover *)sharedPopover;
4243

BFColorPickerPopover/BFColorPickerPopover.m

+90-83
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,28 @@ @interface BFColorPickerPopover ()
4444

4545

4646
@implementation BFColorPickerPopover {
47-
NSColor *_color;
47+
NSColor *_color;
4848
}
4949

5050
@synthesize observingColor = _observingColor;
5151

5252
- (void)setObservingColor:(BOOL)observingColor {
53-
if (_observingColor == observingColor) {
54-
return;
55-
}
56-
57-
if (!self.colorPanel) {
58-
observingColor = NO;
59-
}
60-
61-
_observingColor = observingColor;
62-
63-
void *context = (__bridge void *)self;
64-
if (_observingColor) {
65-
[self.colorPanel addObserver:self forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:context];
66-
} else {
67-
[self.colorPanel removeObserver:self forKeyPath:@"color" context:context];
68-
}
53+
if (_observingColor == observingColor) {
54+
return;
55+
}
56+
57+
if (!self.colorPanel) {
58+
observingColor = NO;
59+
}
60+
61+
_observingColor = observingColor;
62+
63+
void *context = (__bridge void *)self;
64+
if (_observingColor) {
65+
[self.colorPanel addObserver:self forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:context];
66+
} else {
67+
[self.colorPanel removeObserver:self forKeyPath:@"color" context:context];
68+
}
6969
}
7070

7171
#pragma mark -
@@ -77,6 +77,7 @@ + (BFColorPickerPopover *)sharedPopover
7777
static dispatch_once_t onceToken;
7878
dispatch_once(&onceToken, ^{
7979
sharedPopover = [[BFColorPickerPopover alloc] init];
80+
sharedPopover.delegate = sharedPopover;
8081
});
8182
return sharedPopover;
8283
}
@@ -85,120 +86,126 @@ - (id)init
8586
{
8687
self = [super init];
8788
if (self) {
88-
self.behavior = NSPopoverBehaviorSemitransient;
89-
_color = [NSColor whiteColor];
90-
}
89+
self.behavior = NSPopoverBehaviorSemitransient;
90+
_color = [NSColor whiteColor];
91+
}
9192
return self;
9293
}
9394

9495
#pragma mark -
9596
#pragma mark Getters & Setters
9697

9798
- (NSColorPanel *)colorPanel {
98-
return ((BFColorPickerViewController *)self.contentViewController).colorPanel;
99+
return ((BFColorPickerViewController *)self.contentViewController).colorPanel;
99100
}
100101

101102
- (NSColor *)color {
102-
return self.colorPanel.color;
103+
return self.colorPanel.color;
103104
}
104105

105106
- (void)setColor:(NSColor *)color {
106-
_color = color;
107-
if (self.isShown) {
108-
self.colorPanel.color = color;
109-
}
107+
_color = color;
108+
if (self.isShown) {
109+
self.colorPanel.color = color;
110+
}
110111
}
111112

112113
#pragma mark -
113114
#pragma mark Popover Lifecycle
114115

115116
- (void)showRelativeToRect:(NSRect)positioningRect ofView:(NSView *)positioningView preferredEdge:(NSRectEdge)preferredEdge {
116-
117-
// Close the popover without an animation if it's already on screen.
118-
if (self.isShown) {
119-
id targetBackup = self.target;
120-
SEL actionBackup = self.action;
121-
BOOL animatesBackup = self.animates;
122-
self.animates = NO;
123-
[self close];
124-
self.animates = animatesBackup;
125-
self.target = targetBackup;
126-
self.action = actionBackup;
127-
}
128-
129-
self.contentViewController = [[BFColorPickerViewController alloc] init];
130-
[super showRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
131-
132-
self.colorPanel.color = _color;
133-
self.observingColor = YES;
117+
118+
// Close the popover without an animation if it's already on screen.
119+
if (self.isShown) {
120+
id targetBackup = self.target;
121+
SEL actionBackup = self.action;
122+
BOOL animatesBackup = self.animates;
123+
self.animates = NO;
124+
[self close];
125+
self.animates = animatesBackup;
126+
self.target = targetBackup;
127+
self.action = actionBackup;
128+
}
129+
130+
self.contentViewController = [[BFColorPickerViewController alloc] init];
131+
[super showRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
132+
133+
self.colorPanel.color = _color;
134+
self.observingColor = YES;
134135
}
135136

136137
// On pressing Esc, close the popover.
137138
- (void)cancelOperation:(id)sender {
138-
[self close];
139+
[self close];
139140
}
140141

141142
- (void)removeTargetAndAction {
142-
self.target = nil;
143-
self.action = nil;
143+
self.target = nil;
144+
self.action = nil;
144145
}
145146

146147
- (void)deactivateColorWell {
147-
[self.colorWell deactivate];
148-
self.colorWell = nil;
148+
[self.colorWell deactivate];
149+
self.colorWell = nil;
149150
}
150151

151152
- (void)closeAndDeactivateColorWell:(BOOL)deactivate removeTarget:(BOOL)removeTarget removeObserver:(BOOL)removeObserver {
152-
153-
if (removeTarget) {
154-
[self removeTargetAndAction];
155-
}
156-
if (removeObserver) {
157-
self.observingColor = NO;
158-
}
159-
160-
// For some strange reason I couldn't figure out, the panel changes it's color when closed.
161-
// To fix this, I reset the color after it's closed.
162-
NSColor *backupColor = self.colorPanel.color;
163-
[super close];
164-
self.colorPanel.color = backupColor;
165-
166-
if (deactivate) {
167-
[self deactivateColorWell];
168-
}
153+
if (removeObserver) {
154+
self.observingColor = NO;
155+
}
156+
157+
// For some strange reason I couldn't figure out, the panel changes it's color when closed.
158+
// To fix this, I reset the color after it's closed.
159+
NSColor *backupColor = self.colorPanel.color;
160+
[super close];
161+
self.colorPanel.color = backupColor;
162+
163+
if (removeTarget) {
164+
[self removeTargetAndAction];
165+
}
166+
167+
if (deactivate) {
168+
[self deactivateColorWell];
169+
}
169170
}
170171

171172
- (void)close {
172-
[self closeAndDeactivateColorWell:YES removeTarget:YES removeObserver:YES];
173+
[self closeAndDeactivateColorWell:YES removeTarget:YES removeObserver:YES];
173174
}
174175

175176
- (BOOL)_delegatePopoverShouldClose:(id)sender {
176-
if ([super _delegatePopoverShouldClose:sender]) {
177-
[self removeTargetAndAction];
178-
self.observingColor = NO;
179-
[self deactivateColorWell];
180-
return YES;
181-
}
182-
return NO;
177+
if ([super _delegatePopoverShouldClose:sender]) {
178+
[self removeTargetAndAction];
179+
self.observingColor = NO;
180+
[self deactivateColorWell];
181+
return YES;
182+
}
183+
return NO;
184+
}
185+
186+
-(void)popoverWillClose:(NSNotification *)notification {
187+
if(_onCloseDelegate) {
188+
[_onCloseDelegate performSelector:@selector(popoverClosed)];
189+
}
183190
}
184191

185192
#pragma mark -
186193
#pragma mark Observation
187194

188195
// Notify the target when the color changes.
189196
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
190-
if (object == self.colorPanel && [keyPath isEqualToString:@"color"] && context == (__bridge void *)self) {
191-
_color = self.colorPanel.color;
192-
if (self.target && self.action && [self.target respondsToSelector:self.action]) {
193-
197+
if (object == self.colorPanel && [keyPath isEqualToString:@"color"] && context == (__bridge void *)self) {
198+
_color = self.colorPanel.color;
199+
if (self.target && self.action && [self.target respondsToSelector:self.action]) {
200+
194201
#pragma clang diagnostic push
195202
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
196-
197-
[self.target performSelector:self.action withObject:self];
198-
203+
204+
[self.target performSelector:self.action withObject:self];
205+
199206
#pragma clang diagnostic pop
200-
}
201-
}
207+
}
208+
}
202209
}
203210

204211
@end

BFColorPickerPopover/BFPopoverColorWell.h

+1
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@
3434

3535
@property (nonatomic) NSRectEdge preferredEdgeForPopover;
3636
@property (nonatomic) BOOL useColorPanelIfAvailable;
37+
@property (nonatomic) NSObject* onCloseDel;
3738

3839
@end

BFColorPickerPopover/BFPopoverColorWell.m

+38-44
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ @interface BFPopoverColorWell ()
4646
@implementation BFPopoverColorWell
4747

4848
- (void)setup {
49-
self.preferredEdgeForPopover = NSMaxXEdge;
50-
self.useColorPanelIfAvailable = YES;
49+
self.preferredEdgeForPopover = NSMaxXEdge;
50+
self.useColorPanelIfAvailable = YES;
5151
}
5252

5353
- (id)initWithCoder:(NSCoder *)coder
@@ -69,58 +69,52 @@ - (id)initWithFrame:(NSRect)frame
6969
}
7070

7171
- (void)activateWithPopover {
72-
if (self.isActive) return;
73-
74-
// Setup and show the popover.
75-
self.popover = [BFColorPickerPopover sharedPopover];
76-
self.popover.delegate = self;
77-
self.popover.color = self.color;
78-
[self.popover showRelativeToRect:self.frame ofView:self.superview preferredEdge:self.preferredEdgeForPopover];
79-
self.popover.colorWell = self;
80-
81-
// Disable the shared color panel, while the NSColorWell implementation is executed.
82-
// This is done by overriding the orderFront: method of NSColorPanel in a category.
83-
[[NSColorPanel sharedColorPanel] disablePanel];
84-
[super activate:YES];
85-
[[NSColorPanel sharedColorPanel] enablePanel];
86-
87-
self.isActive = YES;
72+
if (self.isActive) return;
73+
74+
// Setup and show the popover.
75+
self.popover = [BFColorPickerPopover sharedPopover];
76+
self.popover.color = self.color;
77+
[self.popover showRelativeToRect:self.frame ofView:self.superview preferredEdge:self.preferredEdgeForPopover];
78+
self.popover.colorWell = self;
79+
self.popover.onCloseDelegate = _onCloseDel;
80+
81+
// Disable the shared color panel, while the NSColorWell implementation is executed.
82+
// This is done by overriding the orderFront: method of NSColorPanel in a category.
83+
[[NSColorPanel sharedColorPanel] disablePanel];
84+
[super activate:YES];
85+
[[NSColorPanel sharedColorPanel] enablePanel];
86+
87+
self.isActive = YES;
8888
}
8989

9090
- (void)activate:(BOOL)exclusive {
91-
if (self.isActive) return;
92-
93-
if (self.useColorPanelIfAvailable && [NSColorPanel sharedColorPanelExists] && [[NSColorPanel sharedColorPanel] isVisible]) {
94-
[super activate:exclusive];
95-
self.isActive = YES;
96-
} else {
97-
[self activateWithPopover];
98-
}
91+
if (self.isActive) return;
92+
93+
if (self.useColorPanelIfAvailable && [NSColorPanel sharedColorPanelExists] && [[NSColorPanel sharedColorPanel] isVisible]) {
94+
[super activate:exclusive];
95+
self.isActive = YES;
96+
} else {
97+
[self activateWithPopover];
98+
}
9999
}
100100

101101
- (void)deactivate {
102-
if (!self.isActive) return;
103-
[super deactivate];
104-
self.popover.colorWell = nil;
105-
self.popover.delegate = nil;
106-
self.popover = nil;
107-
self.isActive = NO;
102+
if (!self.isActive) return;
103+
[super deactivate];
104+
self.popover.colorWell = nil;
105+
self.popover = nil;
106+
self.isActive = NO;
108107
}
109108

110109
// Force using a popover (even if useColorPanelIfAvailable = YES), when the user double clicks the well.
111110
- (void)mouseDown:(NSEvent *)theEvent {
112-
if([theEvent clickCount] == 2 && [NSColorPanel sharedColorPanelExists] && [[NSColorPanel sharedColorPanel] isVisible]) {
113-
[self deactivate];
114-
[self activateWithPopover];
115-
} else {
116-
[super mouseDown:theEvent];
117-
}
118-
119-
}
120-
121-
- (void)popoverDidClose:(NSNotification *)notification
122-
{
123-
[self deactivate];
111+
if([theEvent clickCount] == 2 && [NSColorPanel sharedColorPanelExists] && [[NSColorPanel sharedColorPanel] isVisible]) {
112+
[self deactivate];
113+
[self activateWithPopover];
114+
} else {
115+
[super mouseDown:theEvent];
116+
}
117+
124118
}
125119

126120
@end

0 commit comments

Comments
 (0)