2 // VLCHUDCheckboxCell.m
5 // Created by BinaryGod on 5/25/08.
7 // Copyright (c) 2008, Tim Davis (BinaryMethod.com, binary.god@gmail.com)
8 // All rights reserved.
10 // Redistribution and use in source and binary forms, with or without modification,
11 // are permitted provided that the following conditions are met:
13 // Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
16 // Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation and/or
18 // other materials provided with the distribution.
20 // Neither the name of the BinaryMethod.com nor the names of its contributors
21 // may be used to endorse or promote products derived from this software without
22 // specific prior written permission.
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
25 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
30 // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 // POSSIBILITY OF SUCH DAMAGE.
35 #import "VLCHUDCheckboxCell.h"
36 #import "CompatibilityFixes.h"
38 @implementation VLCHUDCheckboxCell
42 /* On 10.10+ we do not want custom drawing, therefore we swap out the implementation
43 * of the selectors below with their original implementations.
44 * Just calling super will not work, as the AppKit implementation for the NSButton
45 * checkbox checks if the drawing related selectors below are overriden, and if
46 * that is the case, will fall back to legacy drawing, without animation,
47 * without vibrancy and non-layer-based.
49 if (OSX_YOSEMITE_AND_HIGHER) {
50 swapoutOverride([VLCHUDCheckboxCell class], @selector(initWithCoder:));
51 swapoutOverride([VLCHUDCheckboxCell class], @selector(drawImage:withFrame:inView:));
52 swapoutOverride([VLCHUDCheckboxCell class], @selector(drawTitle:withFrame:inView:));
56 - (instancetype)initWithCoder:(NSCoder *)coder
58 self = [super initWithCoder:coder];
61 _cellTextColor = [NSColor whiteColor];
62 _disabledCellTextColor = [NSColor colorWithCalibratedWhite:1.0f alpha:0.5f];
63 _strokeColor = [NSColor whiteColor];
64 _disabledStrokeColor = [NSColor colorWithCalibratedWhite:1.0f alpha:0.5f];
67 _normalGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:1.0f]
68 endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:1.0f]];
69 _highlightGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.451f green:0.451f blue:0.455f alpha:1.0f]
70 endingColor:[NSColor colorWithDeviceRed:0.318f green:0.318f blue:0.318f alpha:1.0f]];
71 _pushedGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.451f green:0.451f blue:0.455f alpha:1.0f]
72 endingColor:[NSColor colorWithDeviceRed:0.318f green:0.318f blue:0.318f alpha:1.0f]];
77 - (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView
79 // Set frame size correctly
80 NSRect backgroundFrame = frame;
81 if (self.controlSize == NSSmallControlSize) {
83 frame.origin.y += 2.5;
84 frame.size.width -= 5;
85 frame.size.height -= 5;
86 backgroundFrame = NSInsetRect(frame, 1.5, 1.5);
87 } else if (self.controlSize == NSMiniControlSize) {
88 frame.origin.x += 2.5;
90 frame.size.width -= 5;
91 frame.size.height -= 5;
92 backgroundFrame = NSInsetRect(frame, 2, 2);
96 NSBezierPath *backgroundPath = [NSBezierPath bezierPathWithRoundedRect:backgroundFrame
100 // Draw background and stroke
101 if([self isEnabled]) {
102 if ([self isHighlighted]) {
103 [_highlightGradient drawInBezierPath:backgroundPath angle:90.0];
105 [_normalGradient drawInBezierPath:backgroundPath angle:90.0];
107 [_strokeColor setStroke];
109 [_disabledStrokeColor setStroke];
112 [NSGraphicsContext saveGraphicsState];
113 if ([super showsFirstResponder] && [[[self controlView] window] isKeyWindow] &&
114 ([self focusRingType] == NSFocusRingTypeDefault ||
115 [self focusRingType] == NSFocusRingTypeExterior)) {
116 NSSetFocusRingStyle(NSFocusRingOnly);
118 [backgroundPath setLineWidth:1.0];
119 [backgroundPath stroke];
120 [NSGraphicsContext restoreGraphicsState];
123 if ([self intValue]) {
124 NSBezierPath* bezierPath = [NSBezierPath bezierPath];
125 [bezierPath moveToPoint: NSMakePoint(NSMinX(frame) + 3.0, NSMidY(frame) - 2.0)];
126 [bezierPath lineToPoint: NSMakePoint(NSMidX(frame), NSMidY(frame) + 2.0)];
127 [bezierPath lineToPoint: NSMakePoint((NSMinX(frame) + NSWidth(frame) - 1), NSMinY(frame) - 2.0)];
128 [bezierPath setLineWidth: 1.5];
130 if([self isEnabled]) {
131 [_strokeColor setStroke];
133 [_disabledStrokeColor setStroke];
139 - (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView
141 NSMutableAttributedString *newTitle = [title mutableCopy];
143 if([self isEnabled]) {
144 [newTitle addAttribute:NSForegroundColorAttributeName
146 range:NSMakeRange(0, [newTitle length])];
148 [newTitle addAttribute:NSForegroundColorAttributeName
149 value:_disabledCellTextColor
150 range:NSMakeRange(0, [newTitle length])];
153 return [super drawTitle: newTitle withFrame: frame inView: controlView];