Revision: 15024
http://sourceforge.net/p/skim-app/code/15024
Author: hofman
Date: 2025-03-26 16:44:37 +0000 (Wed, 26 Mar 2025)
Log Message:
-----------
Use segmented control and auto layout fo background of color swatch control.
Its alignment rect should always be the bezel rect.
Modified Paths:
--------------
trunk/SKColorSwatch.h
trunk/SKColorSwatch.m
Modified: trunk/SKColorSwatch.h
===================================================================
--- trunk/SKColorSwatch.h 2025-03-25 22:56:08 UTC (rev 15023)
+++ trunk/SKColorSwatch.h 2025-03-26 16:44:37 UTC (rev 15024)
@@ -42,12 +42,12 @@
extern NSString *SKColorSwatchColorsChangedNotification;
-@class SKColorSwatchBackgroundView, SKColorSwatchItemView;
+@class SKColorSwatchItemView;
@interface SKColorSwatch : NSControl <NSDraggingSource, NSAccessibilityGroup> {
NSMutableArray<NSColor *> *colors;
NSMutableArray<SKColorSwatchItemView *> *itemViews;
- SKColorSwatchBackgroundView *backgroundView;
+ NSControl *backgroundView;
CGFloat bezelHeight;
NSInteger clickedIndex;
Modified: trunk/SKColorSwatch.m
===================================================================
--- trunk/SKColorSwatch.m 2025-03-25 22:56:08 UTC (rev 15023)
+++ trunk/SKColorSwatch.m 2025-03-26 16:44:37 UTC (rev 15024)
@@ -64,12 +64,7 @@
#define BEZEL_INSET_BOTTOM 2.0
#define COLOR_INSET 2.0
-#define LARGE_SIZE_HEIGHT_OUTSET 4.5
-#define LARGE_SIZE_WIDTH_OUTSET 5.0
-
-#define SKControlSizeLarge 3
-
-static inline CGFloat swatchRadius(NSControlSize controlSize) {
+static inline CGFloat cornerRadius(NSControlSize controlSize) {
if (@available(macOS 11.0, *)) {
switch (controlSize) {
case NSControlSizeRegular: return 3.0;
@@ -76,30 +71,13 @@
case NSControlSizeSmall: return 2.0;
case NSControlSizeMini: return 1.0;
case NSControlSizeLarge: return 4.0;
- default: return 3.0;
}
} else {
- switch (controlSize) {
- case NSControlSizeRegular: return 2.0;
- case NSControlSizeSmall: return 1.0;
- case NSControlSizeMini: return 0.5;
- default: return 2.0;
- }
+ return controlSize == NSControlSizeRegular ? 2.0 : 1.0;
}
}
-static inline CGFloat bezelWidthOffset(NSControlSize controlSize) {
- switch (controlSize) {
- case NSControlSizeRegular: return 4.0;
- case NSControlSizeSmall: return 0.0;
- case NSControlSizeMini: return 0.0;
- case SKControlSizeLarge: return 2.0;
- default: return 4.0;
- }
-}
-
-@interface SKColorSwatchBackgroundView : NSControl
-@property (nonatomic) CGFloat bezelWidth;
+@interface SKColorSwatchBackgroundView : NSSegmentedControl
@end
typedef NS_ENUM(NSUInteger, SKColorSwatchDropLocation) {
@@ -169,11 +147,16 @@
[self commonInit];
- SKColorSwatchBackgroundView *view = [[SKColorSwatchBackgroundView
alloc] initWithFrame:[self bounds]];
- [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- [view setBezelWidth:[self intrinsicContentSize].width];
- [self addSubview:view];
- backgroundView = view;
+ backgroundView = [[SKColorSwatchBackgroundView alloc]
initWithFrame:[self bounds]];
+ [backgroundView setTranslatesAutoresizingMaskIntoConstraints:NO];
+ [self addSubview:backgroundView];
+ NSArray *constraints = @[
+ [[backgroundView leadingAnchor] constraintEqualToAnchor:[self
leadingAnchor]],
+ [[self trailingAnchor] constraintEqualToAnchor:[backgroundView
trailingAnchor]],
+ [[backgroundView topAnchor] constraintEqualToAnchor:[self
topAnchor]],
+ [[self bottomAnchor] constraintEqualToAnchor:[backgroundView
bottomAnchor]]];
+ [constraints setValue:@YES forKey:@"shouldBeArchived"];
+ [NSLayoutConstraint activateConstraints:constraints];
SKColorSwatchItemView *itemView = [[SKColorSwatchItemView alloc]
initWithFrame:[self frameForItemViewAtIndex:0 collapsedIndex:-1]];
[itemView setColor:[NSColor whiteColor]];
@@ -291,20 +274,17 @@
return NSEdgeInsetsMake(BEZEL_INSET_TOP, BEZEL_INSET_LEFT,
BEZEL_INSET_BOTTOM, BEZEL_INSET_RIGHT);
}
-- (void)updateSubviewLayout {
+- (void)updateItemViewFrames {
NSUInteger i, iMax = [itemViews count];
for (i = 0; i < iMax; i++)
[[itemViews objectAtIndex:i] setFrame:[self frameForItemViewAtIndex:i
collapsedIndex:-1]];
- [backgroundView setBezelWidth:[self intrinsicContentSize].width];
}
- (void)updateBezelHeight {
- CGFloat height = [[backgroundView cell] cellSize].height - BEZEL_INSET_TOP
- BEZEL_INSET_BOTTOM;
- if ([backgroundView controlSize] == SKControlSizeLarge)
- height -= 2.0 * LARGE_SIZE_HEIGHT_OUTSET;
+ CGFloat height = [backgroundView intrinsicContentSize].height;
if (fabs(height - bezelHeight) > 0.0) {
bezelHeight = height;
- [self updateSubviewLayout];
+ [self updateItemViewFrames];
[self invalidateIntrinsicContentSize];
if (autoResizes)
[self sizeToFit];
@@ -312,15 +292,9 @@
}
- (void)setControlSize:(NSControlSize)controlSize {
- if (controlSize != [self controlSize]) {
- [super setControlSize:controlSize];
+ [super setControlSize:controlSize];
+ if (controlSize != [backgroundView controlSize]) {
[backgroundView setControlSize:controlSize];
- NSRect bgFrame = [self bounds];
- if (controlSize == SKControlSizeLarge) {
- bgFrame = NSInsetRect(bgFrame, -LARGE_SIZE_WIDTH_OUTSET,
-LARGE_SIZE_HEIGHT_OUTSET);
- bgFrame.origin.y = ceil(bgFrame.origin.y);
- }
- [backgroundView setFrame:bgFrame];
[self updateBezelHeight];
}
}
@@ -336,7 +310,7 @@
- (void)drawFocusRingMask {
NSRect rect = [self focusRingMaskBounds];
if (NSIsEmptyRect(rect) == NO) {
- CGFloat r = swatchRadius([self controlSize]);
+ CGFloat r = cornerRadius([self controlSize]);
[[NSBezierPath bezierPathWithRoundedRect:rect xRadius:r yRadius:r]
fill];
}
}
@@ -357,19 +331,20 @@
- (void)handleKeyOrMainStateChanged:(NSNotification *)note {
if ([[note name] isEqualToString:NSWindowDidResignMainNotification])
[self deactivate];
- [[self subviews] setValue:[NSNumber numberWithInt:YES]
forKey:@"needsDisplay"];
+ [[self subviews] setValue:@YES forKey:@"needsDisplay"];
}
- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
NSWindow *oldWindow = [self window];
NSArray *names = @[NSWindowDidBecomeMainNotification,
NSWindowDidResignMainNotification, NSWindowDidBecomeKeyNotification,
NSWindowDidResignKeyNotification];
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if (oldWindow) {
for (NSString *name in names)
- [[NSNotificationCenter defaultCenter] removeObserver:self
name:name object:oldWindow];
+ [nc removeObserver:self name:name object:oldWindow];
}
if (newWindow) {
for (NSString *name in names)
- [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleKeyOrMainStateChanged:) name:name object:newWindow];
+ [nc addObserver:self
selector:@selector(handleKeyOrMainStateChanged:) name:name object:newWindow];
}
[self deactivate];
[super viewWillMoveToWindow:newWindow];
@@ -405,7 +380,7 @@
NSColor *color = [colors objectAtIndex:i];
- CGFloat r = swatchRadius(NSControlSizeRegular) - 0.5;
+ CGFloat r = cornerRadius(NSControlSizeRegular) - 0.5;
NSImage *image = [NSImage
bitmapImageWithSize:NSMakeSize(12.0, 12.0) forView:self drawingHandler:^(NSRect
rect){
[color drawSwatchInRect:NSInsetRect(rect, 1.0, 1.0)];
@@ -518,7 +493,7 @@
[[itemViews objectAtIndex:iMax] removeFromSuperview];
[itemViews removeObjectAtIndex:iMax];
}
- [self updateSubviewLayout];
+ [self updateItemViewFrames];
[self invalidateIntrinsicContentSize];
[[NSNotificationCenter defaultCenter]
postNotificationName:SKColorSwatchColorsChangedNotification object:self];
}
@@ -630,11 +605,8 @@
NSUInteger i = 0;
for (SKColorSwatchItemView *itemView in itemViews)
[[itemView animator] setFrame:[self frameForItemViewAtIndex:i++
collapsedIndex:collapsedIndex]];
- if (NSEqualSizes(size, NSZeroSize) == NO) {
- [[backgroundView animator] setBezelWidth:size.width - BEZEL_INSET_LEFT
- BEZEL_INSET_RIGHT];
- if (autoResizes)
- [[self animator] setFrameSize:size];
- }
+ if (NSEqualSizes(size, NSZeroSize) == NO && autoResizes)
+ [[self animator] setFrameSize:size];
}
- (void)insertColor:(NSColor *)color atIndex:(NSInteger)i {
@@ -888,25 +860,17 @@
@implementation SKColorSwatchBackgroundView
-@dynamic bezelWidth;
-
-+ (id)defaultAnimationForKey:(NSString *)key {
- if ([key isEqualToString:@"bezelWidth"]) {
- CABasicAnimation *anim = [CABasicAnimation animation];
- [anim setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionDefault]];
- return anim;
- } else
- return [super defaultAnimationForKey:key];
-}
-
- (instancetype)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
- NSSegmentedCell *cell = [[NSSegmentedCell alloc] init];
- [cell setSegmentCount:1];
- [cell setSegmentStyle:NSSegmentStyleTexturedSquare];
- [cell setWidth:fmax(0.0, NSWidth(frameRect) -
bezelWidthOffset(NSControlSizeRegular) - BEZEL_INSET_LEFT - BEZEL_INSET_RIGHT)
forSegment:0];
- [self setCell:cell];
+ [self setSegmentCount:1];
+ [self setWidth:0.0 forSegment:0];
+ [self setSegmentDistribution:NSSegmentDistributionFill];
+ [self setSegmentStyle:NSSegmentStyleTexturedSquare];
+ [self setContentHuggingPriority:1
forOrientation:NSLayoutConstraintOrientationHorizontal];
+ [self setContentHuggingPriority:1
forOrientation:NSLayoutConstraintOrientationVertical];
+ [self setContentCompressionResistancePriority:1
forOrientation:NSLayoutConstraintOrientationHorizontal];
+ [self setContentCompressionResistancePriority:1
forOrientation:NSLayoutConstraintOrientationVertical];
}
return self;
}
@@ -913,23 +877,20 @@
- (BOOL)canBecomeKeyView { return NO; }
-- (CGFloat)bezelWidth {
- return [[self cell] widthForSegment:0] + bezelWidthOffset([self
controlSize]);
+- (void)mouseDown:(NSEvent *)event {
+ [[self superview] mouseDown:event];
}
-- (void)setBezelWidth:(CGFloat)width {
- [[self cell] setWidth:width - bezelWidthOffset([self controlSize])
forSegment:0];
- [self setNeedsDisplay:YES];
+- (void)rightMouseDown:(NSEvent *)event {
+ [[self superview] rightMouseDown:event];
}
-- (void)mouseDown:(NSEvent *)event {
- [[self superview] mouseDown:event];
-}
-
- (void)keyDown:(NSEvent *)event {
[[self superview] keyDown:event];
}
+- (void)performClick:(id)sender {}
+
- (BOOL)isAccessibilityElement {
return NO;
}
@@ -992,7 +953,7 @@
if (NSWidth(rect) < 5.0)
return;
rect = NSInsetRect(rect, COLOR_INSET, COLOR_INSET);
- CGFloat r = swatchRadius([(SKColorSwatch *)[self superview] controlSize]);
+ CGFloat r = cornerRadius([(SKColorSwatch *)[self superview] controlSize]);
BOOL disabled = NO;
if (@available(macOS 10.14, *))
disabled = [[self window] isMainWindow] == NO && [[self window]
isKeyWindow] == NO && ([self isDescendantOf:[[self window] contentView]] == NO
|| [[self window] isKindOfClass:NSClassFromString(@"NSToolbarSnapshotWindow")]);
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