Revision: 15030
http://sourceforge.net/p/skim-app/code/15030
Author: hofman
Date: 2025-03-27 16:53:35 +0000 (Thu, 27 Mar 2025)
Log Message:
-----------
Animate color swatch width for autolayout. Always update colors and itemViews
before animating for insert/remove/move.
Modified Paths:
--------------
trunk/SKColorSwatch.h
trunk/SKColorSwatch.m
Modified: trunk/SKColorSwatch.h
===================================================================
--- trunk/SKColorSwatch.h 2025-03-27 10:23:44 UTC (rev 15029)
+++ trunk/SKColorSwatch.h 2025-03-27 16:53:35 UTC (rev 15030)
@@ -49,6 +49,7 @@
NSMutableArray<SKColorSwatchItemView *> *itemViews;
NSControl *backgroundView;
CGFloat bezelHeight;
+ CGFloat bezelWidth;
NSInteger clickedIndex;
NSInteger selectedIndex;
Modified: trunk/SKColorSwatch.m
===================================================================
--- trunk/SKColorSwatch.m 2025-03-27 10:23:44 UTC (rev 15029)
+++ trunk/SKColorSwatch.m 2025-03-27 16:53:35 UTC (rev 15030)
@@ -108,15 +108,25 @@
@interface SKColorSwatch ()
@property (nonatomic) NSInteger selectedColorIndex;
-- (NSRect)frameForItemViewAtIndex:(NSInteger)anIndex
collapsedIndex:(NSInteger)collapsedIndex;
+@property (nonatomic) CGFloat bezelWidth;
+- (NSRect)frameForItemViewAtIndex:(NSInteger)anIndex;
- (void)setColor:(NSColor *)color atIndex:(NSInteger)i
fromPanel:(BOOL)fromPanel;
@end
@implementation SKColorSwatch
-@synthesize colors, autoResizes, selects, alternate,
clickedColorIndex=clickedIndex, selectedColorIndex=selectedIndex;
+@synthesize colors, autoResizes, selects, alternate,
clickedColorIndex=clickedIndex, selectedColorIndex=selectedIndex, bezelWidth;
@dynamic color;
++ (id)defaultAnimationForKey:(NSAnimatablePropertyKey)key {
+ if ([key isEqualToString:@"bezelWidth"]) {
+ CABasicAnimation *anim = [CABasicAnimation animation];
+ [anim setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionDefault]];
+ return anim;
+ } else
+ return [super defaultAnimationForKey:key];
+}
+
- (Class)valueClassForBinding:(NSString *)binding {
if ([binding isEqualToString:COLORS_KEY])
return [NSArray class];
@@ -130,6 +140,8 @@
selectedIndex = -1;
draggedIndex = -1;
+ bezelWidth = 0.0;
+
[self registerForDraggedTypes:[NSColor
readableTypesForPasteboard:[NSPasteboard
pasteboardWithName:NSPasteboardNameDrag]]];
}
@@ -154,7 +166,7 @@
[constraints setValue:@YES forKey:@"shouldBeArchived"];
[NSLayoutConstraint activateConstraints:constraints];
- SKColorSwatchItemView *itemView = [[SKColorSwatchItemView alloc]
initWithFrame:[self frameForItemViewAtIndex:0 collapsedIndex:-1]];
+ SKColorSwatchItemView *itemView = [[SKColorSwatchItemView alloc]
initWithFrame:[self frameForItemViewAtIndex:0]];
[itemView setColor:[NSColor whiteColor]];
[self addSubview:itemView];
itemViews = [[NSMutableArray alloc] initWithObjects:itemView, nil];
@@ -214,16 +226,14 @@
return rect;
}
-- (NSRect)frameForItemViewAtIndex:(NSInteger)anIndex
collapsedIndex:(NSInteger)collapsedIndex {
- NSInteger i = anIndex;
- if (collapsedIndex != -1 && anIndex > collapsedIndex)
- i--;
- NSRect rect = NSInsetRect([self frameForColorAtIndex:i], -COLOR_INSET,
-COLOR_INSET);
- if (collapsedIndex == anIndex)
- rect.size.width -= DISTANCE_BETWEEN_COLORS;
- return rect;
+- (NSRect)frameForItemViewAtIndex:(NSInteger)anIndex {
+ return NSInsetRect([self frameForColorAtIndex:anIndex], -COLOR_INSET,
-COLOR_INSET);
}
+- (NSRect)frameForCollapsedItemViewAtIndex:(NSInteger)anIndex {
+ return SKShrinkRect([self frameForItemViewAtIndex:anIndex],
DISTANCE_BETWEEN_COLORS, NSMaxXEdge);
+}
+
- (NSInteger)colorIndexAtPoint:(NSPoint)point {
NSRect rect = [self frameForColorAtIndex:0];
NSInteger i, count = [colors count];
@@ -249,17 +259,21 @@
return count;
}
-- (NSSize)sizeForNumberOfColors:(NSUInteger)count {
- NSEdgeInsets insets = [self alignmentRectInsets];
- return NSMakeSize(COLOR_INSET + count * DISTANCE_BETWEEN_COLORS +
insets.left + insets.right, bezelHeight + insets.bottom + insets.top);
+- (CGFloat)contentWidth {
+ return COLOR_INSET + [colors count] * DISTANCE_BETWEEN_COLORS;
}
- (NSSize)intrinsicContentSize {
- return NSMakeSize(COLOR_INSET + [colors count] * DISTANCE_BETWEEN_COLORS,
bezelHeight);
+ return NSMakeSize(bezelWidth ?: [self contentWidth], bezelHeight);
}
+- (NSSize)intrinsicFrameSize {
+ NSEdgeInsets insets = [self alignmentRectInsets];
+ return NSMakeSize([self contentWidth] + insets.left + insets.right,
bezelHeight + insets.bottom + insets.top);
+}
+
- (void)sizeToFit {
- [self setFrameSize:[self sizeForNumberOfColors:[colors count]]];
+ [self setFrameSize:[self intrinsicFrameSize]];
}
- (NSEdgeInsets)alignmentRectInsets {
@@ -269,7 +283,7 @@
- (void)updateItemViewFrames {
NSUInteger i, iMax = [itemViews count];
for (i = 0; i < iMax; i++)
- [[itemViews objectAtIndex:i] setFrame:[self frameForItemViewAtIndex:i
collapsedIndex:-1]];
+ [[itemViews objectAtIndex:i] setFrame:[self
frameForItemViewAtIndex:i]];
}
- (void)updateBezelHeight {
@@ -492,6 +506,11 @@
[super setEnabled:enabled];
}
+- (void)setBezelWidth:(CGFloat)width {
+ bezelWidth = width;
+ [self invalidateIntrinsicContentSize];
+}
+
#pragma mark Modification
- (void)selectColorAtIndex:(NSInteger)idx {
@@ -585,9 +604,9 @@
[self setColor:color atIndex:i fromPanel:NO];
}
-- (void)animateItemViewsCollapsing:(NSInteger)collapsedIndex {
+- (void)animateItemViewFrames {
[itemViews enumerateObjectsUsingBlock:^(SKColorSwatchItemView *itemView,
NSUInteger i, BOOL *stop){
- NSRect frame = [self frameForItemViewAtIndex:i
collapsedIndex:collapsedIndex];
+ NSRect frame = [self frameForItemViewAtIndex:i];
if (NSEqualRects(frame, [itemView frame]) == NO)
[[itemView animator] setFrame:frame];
}];
@@ -597,9 +616,9 @@
if (color && i >= 0 && i <= (NSInteger)[colors count]) {
[self deactivate];
[self willChangeColors];
+ bezelWidth = [self contentWidth];
[colors insertObject:color atIndex:i];
- [self invalidateIntrinsicContentSize];
- SKColorSwatchItemView *itemView = [[SKColorSwatchItemView alloc]
initWithFrame:[self frameForItemViewAtIndex:i collapsedIndex:i]];
+ SKColorSwatchItemView *itemView = [[SKColorSwatchItemView alloc]
initWithFrame:[self frameForCollapsedItemViewAtIndex:i]];
[itemView setColor:color];
if (i < (NSInteger)[itemViews count])
[self addSubview:itemView positioned:NSWindowBelow
relativeTo:[itemViews objectAtIndex:i]];
@@ -606,19 +625,20 @@
else
[self addSubview:itemView positioned:NSWindowAbove relativeTo:nil];
[itemViews insertObject:itemView atIndex:i];
- NSSize size = [self sizeForNumberOfColors:[colors count]];
+ [self didChangeColors];
[self noteFocusRingMaskChanged];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
- [self animateItemViewsCollapsing:-1];
+ [self animateItemViewFrames];
+ [[self animator] setBezelWidth:[self contentWidth]];
if (autoResizes)
- [[self animator] setFrameSize:size];
+ [[self animator] setFrameSize:[self intrinsicFrameSize]];
}
completionHandler:^{
+ [self setBezelWidth:0.0];
if (autoResizes)
[self sizeToFit];
[self noteFocusRingMaskChanged];
}];
- [self didChangeColors];
}
}
@@ -625,22 +645,25 @@
- (void)removeColorAtIndex:(NSInteger)i {
if (i >= 0 && i < (NSInteger)[colors count] && [colors count] > 1) {
[self deactivate];
- NSSize size = [self sizeForNumberOfColors:[colors count] - 1];
+ [self willChangeColors];
+ bezelWidth = [self contentWidth];
+ [colors removeObjectAtIndex:i];
+ SKColorSwatchItemView *itemView = [itemViews objectAtIndex:i];
+ [itemViews removeObjectAtIndex:i];
+ [self didChangeColors];
[self noteFocusRingMaskChanged];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
- [self animateItemViewsCollapsing:i];
+ [[itemView animator] setFrame:[self
frameForCollapsedItemViewAtIndex:i]];
+ [self animateItemViewFrames];
+ [[self animator] setBezelWidth:[self contentWidth]];
if (autoResizes)
- [[self animator] setFrameSize:size];
+ [[self animator] setFrameSize:[self intrinsicFrameSize]];
}
completionHandler:^{
- [self willChangeColors];
- [colors removeObjectAtIndex:i];
- [[itemViews objectAtIndex:i] removeFromSuperview];
- [itemViews removeObjectAtIndex:i];
- [self didChangeColors];
+ [itemView removeFromSuperview];
+ [self setBezelWidth:0.0];
if (autoResizes)
[self sizeToFit];
- [self invalidateIntrinsicContentSize];
[self noteFocusRingMaskChanged];
}];
}
@@ -658,9 +681,10 @@
[itemViews insertObject:itemView atIndex:to];
if (to > from)
[self addSubview:itemView positioned:NSWindowAbove
relativeTo:[itemViews objectAtIndex:to - 1]];
+ [self didChangeColors];
[self noteFocusRingMaskChanged];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
- [self animateItemViewsCollapsing:-1];
+ [self animateItemViewFrames];
}
completionHandler:^{
if (to < from)
@@ -667,7 +691,6 @@
[self addSubview:itemView positioned:NSWindowBelow
relativeTo:[itemViews objectAtIndex:to + 1]];
[self noteFocusRingMaskChanged];
}];
- [self didChangeColors];
}
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit