fixed: the first version was not functional

This commit is contained in:
daboe01 committed 2026-02-15 18:28:20 +01:00
1 parent 2ff5eb39eb
commit c82e5750f0
2 files changed
+86 -56

No files matched your search

+23 -12
View File
@@ -148,10 +148,13 @@ var SharedColorPanel = nil,
*/
- (void)setColor:(CPColor)aColor
{
if ([_color isEqual:aColor])
return;
_color = aColor;
[_previewView setBackgroundColor:_color];
// Push color via Responder Chain
// Push color via Responder Chain (targets First Responder, i.e., the active CPColorWell)
[CPApp sendAction:@selector(changeColor:) to:nil from:self];
if (_target && _action)
@@ -163,7 +166,7 @@ var SharedColorPanel = nil,
if (_activePicker)
[_activePicker setColor:_color];
if (_opacitySlider)
[_opacitySlider setFloatValue:[_color alphaComponent]];
}
@@ -432,7 +435,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[self setBackgroundColor:[CPColor grayColor]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:@"CPColorDragType"]];
var whiteColor = [CPColor whiteColor];
@@ -555,18 +558,22 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
var pasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];
[pasteboard declareTypes:[CPArray arrayWithObject:@"CPColorDragType"] owner:self];
[pasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:@"CPColorDragType"];
[self dragView:dragView
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard]
pasteboard:pasteboard
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if (aType == CPColorDragType)
if (aType == @"CPColorDragType")
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
}
@@ -576,10 +583,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
pasteboard = [aSender draggingPasteboard],
swatch = nil;
if (![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
if (![pasteboard availableTypeFromArray:[@"CPColorDragType"]] || location.x > [self bounds].size.width - 1 || location.x < 1)
return NO;
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex:FLOOR(location.x / 13)];
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:@"CPColorDragType"]] atIndex:FLOOR(location.x / 13)];
}
@end
@@ -594,7 +601,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
self = [super initWithFrame:aFrame];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:@"CPColorDragType"]];
return self;
}
@@ -613,10 +620,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
var pasteboard = [aSender draggingPasteboard];
if (![pasteboard availableTypeFromArray:[CPColorDragType]])
if (![pasteboard availableTypeFromArray:[@"CPColorDragType"]])
return NO;
var color = [CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]];
var color = [CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:@"CPColorDragType"]];
[_colorPanel setColor:color updatePicker:YES];
}
@@ -639,18 +646,22 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
var pasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];
[pasteboard declareTypes:[CPArray arrayWithObject:@"CPColorDragType"] owner:self];
[pasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:[self backgroundColor]] forType:@"CPColorDragType"];
[self dragView:dragView
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard]
pasteboard:pasteboard
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if (aType == CPColorDragType)
if (aType == @"CPColorDragType")
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:[self backgroundColor]] forType:aType];
}
+63 -44
View File
@@ -26,6 +26,8 @@
@import "CPColor.j"
@import "CPColorPanel.j"
var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiveNotification";
/*!
@ingroup appkit
@class CPColorWell
@@ -38,6 +40,7 @@
{
BOOL _bordered;
CPColor _color;
BOOL _isChangingColorFromPanel; // Guard flag to prevent recursion
}
+ (Class)_binderClassForBinding:(CPString)aBinding
@@ -72,6 +75,31 @@
[theBinding reverseSetValueFor:@"color"];
}
- (BOOL)isFirstResponder
{
return [[self window] firstResponder] === self;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)activate:(BOOL)shouldBeExclusive
{
[[self window] makeFirstResponder:self];
[[CPColorPanel sharedColorPanel] orderFront:self];
}
/*!
Deactivates the color well.
*/
- (void)deactivate
{
if ([self isFirstResponder])
[[self window] makeFirstResponder:nil];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -81,8 +109,8 @@
_color = [CPColor whiteColor];
[self setBordered:YES];
// Register for Drag & Drop
[self registerForDraggedTypes:[CPArray arrayWithObject:CPColorDragType]];
// Register using string literal to avoid dependency issues
[self registerForDraggedTypes:[CPArray arrayWithObject:@"CPColorDragType"]];
}
return self;
@@ -126,15 +154,16 @@
*/
- (void)setColor:(CPColor)aColor
{
if (_color == aColor)
if ([_color isEqual:aColor])
return;
_color = aColor;
[self setNeedsLayout];
// If we are active, update the panel to match us
if ([self isFirstResponder])
// Only push back to the panel if we initiated the change (not if the panel pushed it to us)
// AND if we are the current focus.
if (!_isChangingColorFromPanel && [self isFirstResponder])
[[CPColorPanel sharedColorPanel] setColor:_color];
}
@@ -148,13 +177,17 @@
}
/*!
Standard action method sent by CPColorPanel up the responder chain.
Standard action method sent by CPColorPanel via the Responder Chain.
*/
- (void)changeColor:(id)aSender
{
if ([aSender isKindOfClass:[CPColorPanel class]])
{
_isChangingColorFromPanel = YES;
[self setColor:[aSender color]];
_isChangingColorFromPanel = NO;
// Forward the action to our target (e.g. controller)
[self sendAction:[self action] to:[self target]];
}
}
@@ -167,43 +200,19 @@
If exclusive is \c YES, deactivates any other CPColorWells. \c NO, keeps them active.
@param shouldBeExclusive whether other color wells should be deactivated.
*/
- (void)activate:(BOOL)shouldBeExclusive
{
[[self window] makeFirstResponder:self];
[[CPColorPanel sharedColorPanel] orderFront:self];
}
/*!
Deactivates the color well.
*/
- (void)deactivate
{
if ([self isFirstResponder])
[[self window] makeFirstResponder:nil];
}
/*!
Returns \c YES if the color well is active (is First Responder).
*/
- (BOOL)isActive
{
return [self isFirstResponder];
}
- (BOOL)acceptsFirstResponder
{
return [self isEnabled];
}
- (BOOL)becomeFirstResponder
{
[self setThemeState:CPThemeStateFirstResponder];
var panel = [CPColorPanel sharedColorPanel];
[panel setColor:_color];
// Ensure panel knows who to talk to if it's already open
[panel setTarget:nil];
// Sync panel to our current color
[panel setColor:_color];
// EXPLICITLY set ourselves as the target.
// This ensures that when the user clicks the panel (making Panel key),
// the panel still knows to send messages back to us.
[panel setTarget:self];
[panel setAction:@selector(changeColor:)];
[[CPNotificationCenter defaultCenter] postNotificationName:_CPColorWellDidBecomeExclusiveNotification object:self];
@@ -214,6 +223,13 @@
- (BOOL)resignFirstResponder
{
[self unsetThemeState:CPThemeStateFirstResponder];
var panel = [CPColorPanel sharedColorPanel];
// Clean up if we were the target
if ([panel target] == self)
[panel setTarget:nil];
return YES;
}
@@ -224,7 +240,7 @@
{
if (![self isEnabled])
return;
[self activate:YES];
}
@@ -235,7 +251,7 @@
{
var pasteboard = [sender draggingPasteboard];
if ([[pasteboard types] containsObject:CPColorDragType])
if ([[pasteboard types] containsObject:@"CPColorDragType"])
{
[self setThemeState:CPThemeStateHighlighted];
return CPDragOperationCopy;
@@ -253,17 +269,20 @@
{
var pasteboard = [sender draggingPasteboard];
if ([[pasteboard types] containsObject:CPColorDragType])
if ([[pasteboard types] containsObject:@"CPColorDragType"])
{
var data = [pasteboard dataForType:CPColorDragType],
var data = [pasteboard dataForType:@"CPColorDragType"],
newColor = [CPKeyedUnarchiver unarchiveObjectWithData:data];
if (newColor)
if (newColor && [newColor isKindOfClass:[CPColor class]])
{
[self setColor:newColor];
[self sendAction:[self action] to:[self target]];
[self activate:YES]; // Become active after drop
// Activate nicely after drop
[self activate:YES];
[self unsetThemeState:CPThemeStateHighlighted];
return YES;
}
}
@@ -386,7 +405,7 @@ var CPColorWellColorKey = "CPColorWellColorKey",
{
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self registerForDraggedTypes:[CPArray arrayWithObject:CPColorDragType]];
[self registerForDraggedTypes:[CPArray arrayWithObject:@"CPColorDragType"]];
}
return self;