Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions DFColorWell/DFColorGridView.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ - (instancetype)initWithFrame:(NSRect)frame
_borderPadding = 6.0;
_cellBorderLinewidth = 0.5;
_intercellSpacing = 2.0;
_cellWidth = 44.0;
_cellHeight = 23.0;
_cellWidth = 37.0;
_cellHeight = 20.0;
_cellBorderColor = [[NSColor darkGrayColor] colorWithAlphaComponent:0.5];

}
Expand Down Expand Up @@ -151,6 +151,9 @@ - (NSSize) intrinsicContentSize {

- (void) mouseDown:(NSEvent *)theEvent {

_mouseDownInColumnIndex = NSNotFound;
_mouseDownInRowIndex = NSNotFound;

NSUInteger columns = [_colorWell.delegate numberOfColumnsInColorWell:_colorWell];
NSUInteger rows = [_colorWell.delegate numberOfRowsInColorWell:_colorWell];
NSPoint locationInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
Expand All @@ -173,6 +176,10 @@ - (void) mouseDown:(NSEvent *)theEvent {

- (void) mouseUp:(NSEvent *)theEvent {

if (_mouseDownInRowIndex == NSNotFound || _mouseDownInColumnIndex == NSNotFound) {
return;
}

_mouseIsDown = NO;
//NSLog(@"%s", __PRETTY_FUNCTION__);

Expand All @@ -199,7 +206,6 @@ - (void) mouseUp:(NSEvent *)theEvent {
}
}


if ((_mouseDownInColumnIndex == mouseUpInColumnIndex) && (_mouseDownInRowIndex == mouseUpInRowIndex)) {
selectedColor = [_colorWell.delegate colorWell:_colorWell colorAtColumn:_mouseDownInColumnIndex row:_mouseDownInRowIndex];
if (selectedColor) {
Expand Down
7 changes: 6 additions & 1 deletion DFColorWell/DFColorWell.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
*/
- (NSColor*) colorWell:(DFColorWell*)colorWell colorAtColumn:(NSUInteger)column row:(NSUInteger)row;

@optional

- (void) colorWellWillChooseColor:(DFColorWell*)colorWell;
- (void) colorWellDidChooseColor:(DFColorWell*)colorWell;

@end

/**
Expand All @@ -73,7 +78,7 @@
@warning `DFColorWell` is not a drop in replacement for a `NSColorWell` because it does not attempt to implement the same interface.
*/
IB_DESIGNABLE
@interface DFColorWell : NSControl <NSDraggingSource, NSDraggingDestination>
@interface DFColorWell : NSControl <NSDraggingSource, NSDraggingDestination, NSPopoverDelegate>


///-------------------------
Expand Down
128 changes: 73 additions & 55 deletions DFColorWell/DFColorWell.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
#import "DFColorWell.h"
#import "DFColorGridView.h"

@interface DFColorWell ()

- (void) handlePrivateColorWellDeactivate;

@end

@interface DFPrivateColorWell : NSColorWell
@property (weak) DFColorWell *colorWell;
@end

@implementation DFPrivateColorWell

- (void)deactivate {
[_colorWell handlePrivateColorWellDeactivate];
[super deactivate];
}

@end

#pragma mark - Build-in color well delegate

@interface DFColorGridViewDefaultDelegate : NSObject <DFColorWellDelegate>
Expand Down Expand Up @@ -132,34 +151,14 @@ @interface DFColorWell ()

@property DFColorGridViewDefaultDelegate *defaultDelegate;

@property DFPrivateColorWell *privateColorWell;

@end

@implementation DFColorWell

- (void)dealloc {

[[NSNotificationCenter defaultCenter] removeObserver:self];

if ([NSColorPanel sharedColorPanelExists]) {
NSColorPanel *panel = [NSColorPanel sharedColorPanel];
BOOL needToModifyTarget = NO;

@try {
// The NSColorPanel only has a setter for the target but no getter. But it has a private
// variable named "_target" which we can query using KVC (this is App Store safe). If
// Apple ever decides to remove the variable, the `valueForKey:` will throw an exception
// so we need to be prepared for that.
id target = [panel valueForKey:@"target"];
needToModifyTarget = target == self;
}
@catch (NSException *exception) {
}

if (needToModifyTarget) {
panel.target = nil;
panel.action = NULL;
}
}
+ (BOOL) automaticallyNotifiesObserversOfColor {
return NO;
}

- (void) awakeFromNib {
Expand Down Expand Up @@ -216,11 +215,11 @@ - (NSString*) view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPo
if (view == self) {

if (data == kDFColorSwatchTooltipArea) {
return @"Click to choose a colour.";
return NSLocalizedStringWithDefaultValue( @"DFCOLORWELL_SHOW_COLOR_POPOVER", nil, [NSBundle mainBundle], @"Click to choose a color", @"Tool tip to select a color" );
}

if (data == kDFButtonTooltipArea) {
return @"Click to show more colours or show your own.";
return NSLocalizedStringWithDefaultValue( @"DFCOLORWELL_SHOW_COLOR_PANEL", nil, [NSBundle mainBundle], @"Click to show all colors", @"Tool tip to show the color panel" );
}
}
return nil;
Expand Down Expand Up @@ -578,6 +577,7 @@ + (void) drawColorSwatchWithFrame:(NSRect)frame color:(NSColor*) color shouldDra

// Fill with black, this will end up looking like the upper triangle.
NSBezierPath *path = [NSBezierPath bezierPathWithRect:frame];
path.lineWidth = 0.5;
[[NSColor blackColor] setFill];
[path fill];

Expand Down Expand Up @@ -719,60 +719,62 @@ - (void) _handleMouseUpInColorRect {

// The color grid view knows it own size, set this here
_popover = [[NSPopover alloc] init];
_popover.delegate = self;
[_popover setContentSize:[_colorGridView intrinsicContentSize]];

// Set up popover and show
NSViewController *contentViewController = [[NSViewController alloc] init];
contentViewController.view = _colorGridView;
[_popover setContentViewController:contentViewController];
[_popover setAnimates:NO];
[_popover setBehavior:NSPopoverBehaviorSemitransient];
[_popover setBehavior:NSPopoverBehaviorTransient];
[_popover showRelativeToRect:[self _controlColorSwatchFrame] ofView:self preferredEdge:NSMinYEdge];
}

- (void) _handleMouseUpInButtonRect {

if (_shouldDrawButtonRegionWithSelectedColor == YES) {

_shouldDrawButtonRegionWithSelectedColor = NO;
_shouldDrawDarkerButtonRegion = YES;
NSColorPanel *panel = [NSColorPanel sharedColorPanel];
[panel close];


if (_privateColorWell) {
[_privateColorWell deactivate];
} else {

_shouldDrawDarkerButtonRegion = NO;
_shouldDrawButtonRegionWithSelectedColor = YES;
[self setNeedsDisplay:YES];

NSColorPanel *panel = [NSColorPanel sharedColorPanel];
panel.showsAlpha = YES;
panel.target = self;
panel.action = @selector(handleColorPanelColorSelectionAction:);
panel.color = self.color;
[panel orderFront:nil];

/* Capture the close of the color panel. */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleWindowWillCloseNotification:) name:NSWindowWillCloseNotification object:panel];
if (_popover) {
_popover.delegate = nil;
[self reportDidChooseColor];
}

_privateColorWell = [[DFPrivateColorWell alloc] initWithFrame:NSZeroRect];
[self addSubview:_privateColorWell];
_privateColorWell.hidden = YES;
_privateColorWell.color = self.color;
_privateColorWell.target = self;
_privateColorWell.action = @selector(takeColorFrom:);
_privateColorWell.colorWell = self;
[_privateColorWell activate:YES];
[self reportWillChooseColor];
}
}

#pragma mark - Popover delegate

- (void) popoverWillShow:(NSNotification *)notification {
[self reportWillChooseColor];
}

- (void) popoverDidClose:(NSNotification *)notification {
[self reportDidChooseColor];
}

#pragma mark - Dealing with the NSColorPanel

- (void) handleWindowWillCloseNotification:(NSNotification*)notification {

/* Remove the color panel notification */
NSColorPanel *panel = [NSColorPanel sharedColorPanel];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:panel];

/* Reset all the color panel values */
panel.target = nil;
panel.action = NULL;
- (void) handlePrivateColorWellDeactivate {
[_privateColorWell removeFromSuperview];
_privateColorWell = nil;

_shouldDrawButtonRegionWithSelectedColor = NO;
[self setNeedsDisplay:YES];
[self reportDidChooseColor];
}

- (void) handleColorPanelColorSelectionAction:(id)sender {
Expand Down Expand Up @@ -812,6 +814,22 @@ - (NSColor*) color {
return _color;
}

- (void) takeColorFrom:(id)sender {
self.color = [sender color];
}

- (void) reportWillChooseColor {
if ([_delegate respondsToSelector:@selector(colorWellWillChooseColor:)]) {
[_delegate colorWellWillChooseColor:self];
}
}

- (void) reportDidChooseColor {
if ([_delegate respondsToSelector:@selector(colorWellDidChooseColor:)]) {
[_delegate colorWellDidChooseColor:self];
}
}

#pragma mark - Autolayout

- (NSSize) intrinsicContentSize {
Expand Down