[vlc-devel] [PATCH 1/2] macOS: Fix VLCHUDSegmentedCell text drawing
Marvin Scholz
epirat07 at gmail.com
Thu Jun 15 02:33:07 CEST 2017
The custom cell would draw the text at the wrong location, this is
fixed by this commit. Additionally a lot of cleanup and restructuring
was done.
---
modules/gui/macosx/VLCHUDSegmentedCell.h | 4 -
modules/gui/macosx/VLCHUDSegmentedCell.m | 302 ++++++-------------------------
2 files changed, 53 insertions(+), 253 deletions(-)
diff --git a/modules/gui/macosx/VLCHUDSegmentedCell.h b/modules/gui/macosx/VLCHUDSegmentedCell.h
index 5899d1ca06..8bddb58c41 100644
--- a/modules/gui/macosx/VLCHUDSegmentedCell.h
+++ b/modules/gui/macosx/VLCHUDSegmentedCell.h
@@ -36,7 +36,6 @@
@interface VLCHUDSegmentedCell : NSSegmentedCell
- at property (strong) NSShadow *dropShadow;
@property (strong) NSColor *strokeColor;
@property (strong) NSGradient *highlightGradient;
@property (strong) NSGradient *normalGradient;
@@ -44,7 +43,4 @@
@property (strong) NSColor *cellTextColor;
@property (strong) NSColor *disabledCellTextColor;
--(void)drawInteriorForSegment:(NSInteger)segment withFrame:(NSRect)rect;
--(BOOL)hasText;
-
@end
diff --git a/modules/gui/macosx/VLCHUDSegmentedCell.m b/modules/gui/macosx/VLCHUDSegmentedCell.m
index 3051f12fcc..4b0ead51be 100644
--- a/modules/gui/macosx/VLCHUDSegmentedCell.m
+++ b/modules/gui/macosx/VLCHUDSegmentedCell.m
@@ -34,10 +34,13 @@
#import "VLCHUDSegmentedCell.h"
- at interface NSSegmentedCell (private)
--(NSRect)rectForSegment:(NSInteger)segment inFrame:(NSRect)frame;
+ at interface NSSegmentedCell (Private)
+
+- (NSRect)rectForSegment:(NSInteger)segment inFrame:(NSRect)frame;
+
@end
+
@implementation VLCHUDSegmentedCell
- (instancetype)initWithCoder:(NSCoder *)decoder
@@ -46,11 +49,6 @@ - (instancetype)initWithCoder:(NSCoder *)decoder
self = [super initWithCoder:decoder];
if (self) {
- _dropShadow = [[NSShadow alloc] init];
- [_dropShadow setShadowColor:[NSColor blackColor]];
- [_dropShadow setShadowBlurRadius:2];
- [_dropShadow setShadowOffset:NSMakeSize(0, -1)];
-
_strokeColor = [NSColor colorWithDeviceRed:0.749f green:0.761f blue:0.788f alpha:1.0f];
_highlightGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.451f green:0.451f blue:0.455f alpha:0.5f]
endingColor:[NSColor colorWithDeviceRed:0.318f green:0.318f blue:0.318f alpha:0.5f]];
@@ -65,269 +63,75 @@ - (instancetype)initWithCoder:(NSCoder *)decoder
return self;
}
--(NSSegmentStyle)segmentStyle {
-
- return [super segmentStyle];
-}
-
--(void)setSegmentStyle:(NSSegmentStyle) style {
-
- if(style == NSSegmentStyleSmallSquare || style == NSSegmentStyleRounded) {
-
- [super setSegmentStyle: style];
- }
-}
-
-- (void)drawWithFrame:(NSRect)frame inView:(NSView *)view {
-
- NSBezierPath *border;
-
- switch ([self segmentStyle]) {
- default: // Silence uninitialized variable warnings
- case NSSegmentStyleSmallSquare:
-
- //Adjust frame for shadow
- frame.origin.x += 1.5f;
- frame.origin.y += .5f;
- frame.size.width -= 3;
- frame.size.height -= 3;
-
- border = [[NSBezierPath alloc] init];
- [border appendBezierPathWithRect: frame];
-
- break;
-
- case NSSegmentStyleRounded: //NSSegmentStyleTexturedRounded:
-
- //Adjust frame for shadow
- frame.origin.x += 1.5f;
- frame.origin.y += .5f;
- frame.size.width -= 3;
- frame.size.height -= 3;
-
- border = [[NSBezierPath alloc] init];
-
- [border appendBezierPathWithRoundedRect: frame
- xRadius: 4.0f yRadius: 4.0f];
- break;
- }
-
- //Setup to Draw Border
- [NSGraphicsContext saveGraphicsState];
-
- //Set Shadow + Border Color
- if([self isEnabled])
- {
- [_dropShadow set];
+- (void)drawWithFrame:(NSRect)frame inView:(NSView *)view
+{
+ [_strokeColor setStroke];
+ for (NSInteger segment = 0; segment < self.segmentCount; segment++) {
+ NSRect segmentRect = [self rectForSegment:segment inFrame:frame];
+ [self drawBackgroundForSegment:segment inFrame:segmentRect];
+ [self drawSegment:segment inFrame:segmentRect withView:view];
}
- [_strokeColor set];
-
- //Draw Border + Shadow
- [border stroke];
- [NSGraphicsContext restoreGraphicsState];
-
- int segCount = 0;
-
- while (segCount <= [self segmentCount] -1) {
-
- [self drawSegment: segCount inFrame: frame withView: view];
- segCount++;
- }
+ NSBezierPath* rectanglePath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 0.55, 0.55) xRadius:3.0 yRadius:3.0];
+ [_strokeColor setStroke];
+ [rectanglePath setLineWidth:1.0];
+ [rectanglePath stroke];
}
-- (void)drawSegment:(NSInteger)segment inFrame:(NSRect)frame withView:(NSView *)view {
-
- //Calculate rect for this segment
- NSRect fillRect = [self rectForSegment: segment inFrame: frame];
- NSBezierPath *fillPath;
-
- switch ([self segmentStyle]) {
- default: // Silence uninitialized variable warnings
- case NSSegmentStyleSmallSquare:
-
- if(segment == ([self segmentCount] -1)) {
-
- if(![self hasText]) { fillRect.size.width -= 3; }
- }
-
- fillPath = [[NSBezierPath alloc] init];
- [fillPath appendBezierPathWithRect: fillRect];
-
- break;
-
- case NSSegmentStyleRounded: //NSSegmentStyleTexturedRounded:
-
- //If this is the first segment, draw rounded corners
- if(segment == 0) {
-
- fillPath = [[NSBezierPath alloc] init];
-
- [fillPath appendBezierPathWithRoundedRect: fillRect xRadius: 3 yRadius: 3];
-
- //Setup our joining rect
- NSRect joinRect = fillRect;
- joinRect.origin.x += 4;
- joinRect.size.width -= 4;
-
- [fillPath appendBezierPathWithRect: joinRect];
-
- //If this is the last segment, draw rounded corners
- } else if (segment == ([self segmentCount] -1)) {
-
- fillPath = [[NSBezierPath alloc] init];
-
- if(![self hasText]) { fillRect.size.width -= 3; }
-
- [fillPath appendBezierPathWithRoundedRect: fillRect xRadius: 3 yRadius: 3];
-
- //Setup our joining rect
- NSRect joinRect = fillRect;
- joinRect.size.width -= 4;
-
- [fillPath appendBezierPathWithRect: joinRect];
-
- } else {
- NSAssert(segment != 0 && segment != ([self segmentCount] -1), @"should be a middle segment");
- fillPath = [[NSBezierPath alloc] init];
- [fillPath appendBezierPathWithRect: fillRect];
- }
-
- break;
- }
-
- //Fill our pathss
-
- NSGradient *gradient = nil;
-
- if([self isEnabled])
- {
- if([self selectedSegment] == segment) {
-
- gradient = _highlightGradient;
- } else {
-
- gradient = _normalGradient;
- }
- }
- else {
- gradient = _disabledNormalGradient;
- }
+- (void)drawSegment:(NSInteger)segment inFrame:(NSRect)frame withView:(NSView *)view
+{
+ NSString *segmentText = [self labelForSegment:segment];
- [gradient drawInBezierPath: fillPath angle: 90];
+ NSSize textSize = [segmentText sizeWithAttributes:nil];
- //Draw Segment dividers ONLY if they are
- //inside segments
- if(segment != ([self segmentCount] -1)) {
+ frame.origin.y += (frame.size.height - textSize.height) / 2;
+ frame.size.height -= (frame.size.height - textSize.height) / 2;
- [_strokeColor set];
- [NSBezierPath strokeLineFromPoint: NSMakePoint(fillRect.origin.x + fillRect.size.width , fillRect.origin.y)
- toPoint: NSMakePoint(fillRect.origin.x + fillRect.size.width, fillRect.origin.y + fillRect.size.height)];
- }
+ NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init] ;
+ [paragraphStyle setAlignment:NSTextAlignmentCenter];
- [self drawInteriorForSegment: segment withFrame: fillRect];
+ NSDictionary *attributes = @{ NSForegroundColorAttributeName : (self.isEnabled) ? _cellTextColor : _disabledCellTextColor,
+ NSParagraphStyleAttributeName : paragraphStyle };
+ [segmentText drawInRect:frame withAttributes:attributes];
}
--(void)drawInteriorForSegment:(NSInteger)segment withFrame:(NSRect)rect {
-
- NSAttributedString *newTitle;
-
- //if([self labelForSegment: segment] != nil) {
-
- NSMutableDictionary *textAttributes = [[NSMutableDictionary alloc] initWithCapacity: 0];
-
- [textAttributes setValue: [NSFont controlContentFontOfSize: [NSFont systemFontSizeForControlSize: [self controlSize]]] forKey: NSFontAttributeName];
- if([self isEnabled])
- {
- [textAttributes setValue:_cellTextColor forKey: NSForegroundColorAttributeName];
- }
- else {
- [textAttributes setValue:_disabledCellTextColor forKey: NSForegroundColorAttributeName];
- }
-
-
- if([self labelForSegment: segment]) {
+- (void)drawBackgroundForSegment:(NSInteger)segment inFrame:(NSRect)frame
+{
+ NSGradient *gradient;
- newTitle = [[NSAttributedString alloc] initWithString: [self labelForSegment: segment] attributes: textAttributes];
+ if (self.isEnabled) {
+ gradient = (segment == self.selectedSegment) ? _highlightGradient : _normalGradient;
} else {
-
- newTitle = [[NSAttributedString alloc] initWithString: @"" attributes: textAttributes];
+ gradient = _disabledNormalGradient;
}
- //}
- NSRect textRect = rect;
- NSRect imageRect = rect;
-
- if([super imageForSegment: segment] != nil) {
-
- NSImage *image = [self imageForSegment: segment];
- [image setFlipped: YES];
-
- if([self imageScalingForSegment: segment] == NSImageScaleProportionallyDown) {
-
- CGFloat resizeRatio = (rect.size.height - 4) / [image size].height;
-
- [image setScalesWhenResized: YES];
- [image setSize: NSMakeSize([image size].width * resizeRatio, rect.size.height -4)];
- }
-
- if([self labelForSegment: segment] != nil && ![[self labelForSegment: segment] isEqualToString: @""]) {
+ if (segment > 0 && segment < (self.segmentCount - 1)) {
+ // Middle segments
+ [gradient drawInRect:frame angle:90];
+ return;
+ }
- imageRect.origin.y += (NSMidY(rect) - ([image size].height /2));
- imageRect.origin.x += (NSMidX(rect) - (([image size].width + [newTitle size].width + 5) /2));
- imageRect.size.height = [image size].height;
- imageRect.size.width = [image size].width;
+ CGFloat radius = 3.0;
+ NSBezierPath* fillPath = [NSBezierPath bezierPath];
- textRect.origin.y += (NSMidY(rect) - ([newTitle size].height /2));
- textRect.origin.x += imageRect.origin.x + [image size].width + 5;
- textRect.size.height = [newTitle size].height;
- textRect.size.width = [newTitle size].width;
-
- [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceAtop fraction: 0.5f];
- [newTitle drawInRect: textRect];
-
- } else {
-
- //Draw Image Alone
- imageRect.origin.y += (NSMidY(rect) - ([image size].height /2));
- imageRect.origin.x += (NSMidX(rect) - ([image size].width /2));
- imageRect.size.height = [image size].height;
- imageRect.size.width = [image size].width;
-
- [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceAtop fraction:0.5f];
- }
+ if (segment == 0) {
+ // First segment
+ [fillPath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + radius, NSMinY(frame) + radius) radius:radius startAngle:180 endAngle:270];
+ [fillPath lineToPoint: NSMakePoint(NSMaxX(frame), NSMinY(frame))];
+ [fillPath lineToPoint: NSMakePoint(NSMaxX(frame), NSMaxY(frame))];
+ [fillPath appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + radius, NSMaxY(frame) - radius) radius:radius startAngle:90 endAngle:180];
} else {
-
- textRect.origin.y += (NSMidY(rect) - ([newTitle size].height /2));
- textRect.origin.x += (NSMidX(rect) - ([newTitle size].width /2));
- textRect.size.height = [newTitle size].height;
- textRect.size.width = [newTitle size].width;
-
- if(textRect.origin.x < 3) { textRect.origin.x = 3; }
-
- [newTitle drawInRect: textRect];
- }
-}
-
--(BOOL)hasText {
-
- int i = 0;
- BOOL flag = NO;
-
- while(i <= [self segmentCount] -1) {
-
- if([self labelForSegment: i] != nil && ![[self labelForSegment: i] isEqualToString: @""]) {
-
- flag = YES;
- }
- i++;
+ // Last segment
+ [fillPath moveToPoint: NSMakePoint(NSMinX(frame), NSMinY(frame))];
+ [fillPath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - radius, NSMinY(frame) + radius) radius:radius startAngle:270 endAngle:360];
+ [fillPath appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - radius, NSMaxY(frame) - radius) radius:radius startAngle:0 endAngle:90];
+ [fillPath lineToPoint: NSMakePoint(NSMinX(frame), NSMaxY(frame))];
}
-
- return flag;
+ [fillPath closePath];
+ [gradient drawInBezierPath:fillPath angle:90];
}
- (BOOL)_canAnimate {
-
return NO;
}
--
2.11.0 (Apple Git-81)
More information about the vlc-devel
mailing list