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
Skim-app-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to