简体   繁体   English

NSScroller半透明

[英]NSScroller Translucent

I am using NSScroller in cocoa app. 我在cocoa应用程序中使用NSScroller。 NSScroller is translucent in mojave dark mode but in looks fine in mojave light mode. NSScroller在莫哈韦沙漠模式下是半透明的,但在莫哈韦光线模式下看起来很好。

I have tried subclassing nsscroller and try to change background color. 我已经尝试了子类化nsscroller并尝试更改背景颜色。 it changes background color but translucent effect is not disappearing. 它改变了背景颜色,但半透明效果并没有消失。

class CustomScroller: NSScroller {
- (void)drawRect:(NSRect)dirtyRect {

        NSColor.red.set()
        __NSRectFill(dirtyRect)
        self.drawKnob()
  }
}

Maybe add this to your CustomScroller? 也许将它添加到您的CustomScroller?

- (BOOL) isOpaque {return YES;}

The venerable BGHUDAppKit provides an example of how to draw your own themes from scratch. 古老的BGHUDAppKit提供了一个如何从头开始绘制自己的主题的示例。
Most people hate it because its an unmaintainable mess. 大多数人讨厌它,因为它是一个难以维护的混乱。 Despite this, I've kept my own version up to date for years :) 尽管如此,我保持自己的版本多年来最新:)

You'll need your own 'theme' implementation. 你需要自己的'主题'实现。 For example [[[self theme] scrollerStroke] set]; 例如[[[self theme] scrollerStroke] set]; needs to return an NSColor. 需要返回NSColor。 A good rule of thumb for UI themes: UI主题的一个很好的经验法则:

  • the 10% rule The human eye can distinguish easily between brightness differences of 10%, so for example the scroll bar should be outlined with a color that is 10% brighter than the fill color. 10%规则人眼可以很容易地区分10%的亮度差异,因此例如滚动条的轮廓应该比填充颜色亮10%。 ( outline with 57.0/255.0, fill with 50.0/255.0 ) (概述为57.0 / 255.0,填充50.0 / 255.0)

  • try to use grayscale colors as much as possible. 尝试尽可能使用灰度颜色。

Here's my implementation, with notes included for various OS versions: 这是我的实现,包括各种操作系统版本的注释:

//
//  BGHudScroller.m
//  HUDScroller
//
//  Created by BinaryGod on 5/22/08.
//
//  Copyright (c) 2008, Tim Davis (BinaryMethod.com, binary.god@gmail.com)
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met:
//
//      Redistributions of source code must retain the above copyright notice, this
//  list of conditions and the following disclaimer.
//
//      Redistributions in binary form must reproduce the above copyright notice,
//  this list of conditions and the following disclaimer in the documentation and/or
//  other materials provided with the distribution.
//
//      Neither the name of the BinaryMethod.com nor the names of its contributors
//  may be used to endorse or promote products derived from this software without
//  specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
//  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
//  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
//  POSSIBILITY OF SUCH DAMAGE.

// Special thanks to Matt Gemmell (http://mattgemmell.com/) for helping me solve the
// transparent drawing issues.  Your awesome man!!!

#import "BGHUDScroller.h"
#import "BGThemeMbox.h" // need implementation specific stuff

@implementation BGHUDScroller

#pragma mark Drawing Functions

@synthesize themeKey;
@synthesize LayerKey;

-(id)init {

    self = [super init];

    if(self) {

        self.themeKey = @"gradientTheme";
    }

    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder: aDecoder];

    if(self) {

        if([aDecoder containsValueForKey: @"themeKey"]) {

            self.themeKey = [aDecoder decodeObjectForKey: @"themeKey"];
        } else {
            self.themeKey = @"gradientTheme";
        }
    }

    return self;
}

-(void)encodeWithCoder: (NSCoder *)coder {

    [super encodeWithCoder: coder];

    [coder encodeObject: self.themeKey forKey: @"themeKey"];
}

- (BGTheme *)theme
{
   NSWindow *window = [self window];
   if ( [window isPanel] )
      return [[BGThemeManager keyedManager] themeForKey: @"flatTheme"];
   else
      return [[BGThemeManager keyedManager] themeForKey: [[self target] themeKey]];
}

- (BOOL) preservesContentDuringLiveResize { return YES; }
- (void) setFrameSize:(NSSize)newSize
{
   [super setFrameSize:newSize];

   // A change in size has required the view to be invalidated.
   if ([self inLiveResize])
   {
      NSRect rects[4];
      NSInteger count;
      [self getRectsExposedDuringLiveResize:rects count:&count];
      while (count-- > 0)
      {
         [self setNeedsDisplayInRect:rects[count]];
      }
   }
   else
   {
      [self setNeedsDisplay:YES];
   }
}

- (BOOL) isOpaque {return YES;}
- (void)drawRect:(NSRect)rect {
   waitIfNeeded(self);  

   static SInt32 maj, min, patch;
   if (!maj)
   {
      Gestalt(gestaltSystemVersionMajor, &maj);
      Gestalt(gestaltSystemVersionMinor, &min);
      Gestalt(gestaltSystemVersionBugFix, &patch);
   }

//  if ( sOSVersion >= 0x1070 )
//   {
//       // Lion deprecated scroller arrows altogether, so just let super call my
//      // overrides for drawKnobSlotInRect and drawKnob
//      printf( "drawRect: x%0.2f w %0.2f h %0.2f\n", rect.origin.x, rect.size.width, rect.size.height );
//      [super drawRect:[self bounds]];
//      return;
//   }

   if ( maj == 10 && min < 7 )
   {
      //////////////////////// BEGIN  PRE-LION VERSION ////////////////////////////
      arrowPosition = [[[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain] valueForKey: @"AppleScrollBarVariant"];

      if(arrowPosition == nil) {

         arrowPosition = @"DoubleMax";
      }
      //////////////////////// END  PRE-LION VERSION ////////////////////////////   
    }

    //NSDisableScreenUpdates();

//  [[NSColor headerFillColor] set];
//  NSRectFill([self bounds]);

    // Draw knob-slot.
    [self drawKnobSlotInRect: [self bounds] highlight: YES];

   if (( maj == 10 && min < 7) || ( [self usableParts] != 0 && [self knobProportion] < 1.0 ))
   {
      // Draw knob
      [self drawKnob];
   }

   if ( maj == 10 && min < 7) // PRE-LION VERSION
   {
      // kpk note: we won't get here if running lion, and it works on 10.6.8,
      // also note, drawArrow:highlight: is public API, and drawArrow:highlightPart: is private API override?
      // Draw arrows.  
      [self drawArrow: NSScrollerIncrementArrow highlight: ([self hitPart] == NSScrollerIncrementLine)];
      [self drawArrow: NSScrollerDecrementArrow highlight: ([self hitPart] == NSScrollerDecrementLine)];
    }
    //[[self window] invalidateShadow];

    //NSEnableScreenUpdates();

}

- (void)drawKnob {
   NSRect bounds = [self bounds];
   if ( bounds.size.width < 40 && bounds.size.height < 40 )
      return; // don't draw something stupid if too tiny to show... happens often during initial sizing 

   BOOL isHoriz = ( bounds.size.width > bounds.size.height );

   NSRect knobRect = [self rectForPart: NSScrollerKnob];
   //DLog( @"usable parts %d horiz %d %@ knob %@ frame %@", [self usableParts], isHoriz, NSStringFromRect( [self bounds] ), NSStringFromRect( knobRect ), NSStringFromRect( [self frame] ) );
    if( ! isHoriz ) {

        //Draw Knob
        NSBezierPath *knob = [[NSBezierPath alloc] init];


        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2)))
                                         radius: (knobRect.size.width -2) /2
                                     startAngle: 180
                                       endAngle: 0];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2)))
                                         radius: (knobRect.size.width -2) /2
                                     startAngle: 0
                                       endAngle: 180];

        [[[self theme] scrollerStroke] set];
        [knob fill];

        knobRect.origin.x += 1;
        knobRect.origin.y += 1;
        knobRect.size.width -= 2;
        knobRect.size.height -= 2;

        [knob release];
        knob = [[NSBezierPath alloc] init];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2)))
                                         radius: (knobRect.size.width -2) /2
                                     startAngle: 180
                                       endAngle: 0];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2)))
                                         radius: (knobRect.size.width -2) /2
                                     startAngle: 0
                                       endAngle: 180];

        [[[self theme] scrollerKnobGradient] drawInBezierPath: knob angle: 0];

        [knob release];
    } else {

        //Draw Knob
        NSBezierPath *knob = [[NSBezierPath alloc] init];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
                                         radius: (knobRect.size.height -1) /2
                                     startAngle: 90
                                       endAngle: 270];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
                                         radius: (knobRect.size.height -1) /2
                                     startAngle: 270
                                       endAngle: 90];

        [[[self theme] scrollerStroke] set];
        [knob fill];

        knobRect.origin.x += 1;
        knobRect.origin.y += 1;
        knobRect.size.width -= 2;
        knobRect.size.height -= 2;

        [knob release];
        knob = [[NSBezierPath alloc] init];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
                                         radius: (knobRect.size.height -1) /2
                                     startAngle: 90
                                       endAngle: 270];

        [knob appendBezierPathWithArcWithCenter: NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
                                         radius: (knobRect.size.height -1) /2
                                     startAngle: 270
                                       endAngle: 90];

        [[[self theme] scrollerKnobGradient] drawInBezierPath: knob angle: 90];

        [knob release];
    }
}

- (void)drawArrow:(NSScrollerArrow)arrow highlightPart:(NSUInteger)part {

    if(arrow == NSScrollerDecrementArrow) {

        if(part == (NSUInteger)-1 || part == 0) {

            [self drawDecrementArrow: NO];
        } else {

            [self drawDecrementArrow: YES];
        }
    }

    if(arrow == NSScrollerIncrementArrow) {

        if(part == 1 || part == (NSUInteger)-1) {

            [self drawIncrementArrow: NO];
        } else {

            [self drawIncrementArrow: YES];
        }
    }
}

- (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight {
   NSRect bounds = [self bounds];
   [[[self theme] sliderTrackColor] set];
   NSRectFill(bounds);

   if ( bounds.size.width < 40 && bounds.size.height < 40 )
       return; // don't draw something stupid if too tiny to show... happens often during initial sizing 

   BOOL isHoriz = ( bounds.size.width > bounds.size.height );

    if( ! isHoriz) {
        //Draw Knob Slot
        //[[[self theme] scrollerTrackGradient] drawInRect: rect angle: 0];
        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Adjust rect height for top base
            rect.size.height = 8; // (bgWidth - 2) / 2;

            //Draw Top Base
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            [path appendBezierPathWithArcWithCenter: NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -5)
                                             radius: (rect.size.width ) /2
                                         startAngle: 180
                                           endAngle: 0];

            //Add the rest of the points
            basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);

            [path appendBezierPathWithPoints: basePoints count: 4];

            [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];

            [path release];
        }
    } else {
        //Draw Knob Slot
        //[[[self theme] scrollerTrackGradient] drawInRect: rect angle: 90];
        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Adjust rect height for top base
            rect.size.width = 8; //(bgWidth - 2) / 2;

            //Draw Top Base
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            [path appendBezierPathWithArcWithCenter: NSMakePoint((rect.size.height /2) +5, rect.origin.y + (rect.size.height /2) )
                                             radius: (rect.size.height ) /2
                                         startAngle: 90
                                           endAngle: 270];

            //Add the rest of the points
            basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
            basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);

            [path appendBezierPathWithPoints: basePoints count: 4];

            [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];

            [path release];
        }
    }
}

- (void)drawDecrementArrow:(BOOL)highlighted {
   NSRect bounds = [self bounds];
   if ( bounds.size.width < 40 && bounds.size.height < 40 )
      return; // don't draw something stupid if too tiny to show... happens often during initial sizing 

   BOOL isHoriz = ( bounds.size.width > bounds.size.height );

    if( ! isHoriz) {

        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Draw Decrement Button
            NSRect rect = [self rectForPart: NSScrollerDecrementLine];
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            //Add Notch
            [path appendBezierPathWithArcWithCenter: NSMakePoint((rect.size.width ) /2, (rect.origin.y  - ((rect.size.width ) /2) + 1))
                                             radius: (rect.size.width ) /2
                                         startAngle: 0
                                           endAngle: 180];

            //Add the rest of the points
            basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
            basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);

            //Add Points to Path
            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 0];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3);
            points[1] = NSMakePoint( (rect.size.width /2) +3.5, rect.origin.y + (rect.size.height /2) +3);
            points[2] = NSMakePoint( (rect.size.width /2) -3.5, rect.origin.y + (rect.size.height /2) +3);

            [arrow appendBezierPathWithPoints: points count: 3];

            //[[[self theme] scrollerStroke] set];
            [[[self theme] scrollerStroke] set];
            [arrow fill];

            //Create Devider Line
            [[[self theme] scrollerStroke] set];

            [NSBezierPath strokeLineFromPoint: NSMakePoint(0, (rect.origin.y + rect.size.height) +.5)
                                      toPoint: NSMakePoint(rect.size.width, (rect.origin.y + rect.size.height) +.5)];

            [path release];
            [arrow release];

        } else {

            NSRect rect = [self rectForPart: NSScrollerDecrementLine];

            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            [path appendBezierPathWithArcWithCenter: NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -3)
                                             radius: (rect.size.width ) /2
                                         startAngle: 180
                                           endAngle: 0];

            //Add the rest of the points
            basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);

            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 0];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3);
            points[1] = NSMakePoint( (rect.size.width /2) +3.5, rect.origin.y + (rect.size.height /2) +3);
            points[2] = NSMakePoint( (rect.size.width /2) -3.5, rect.origin.y + (rect.size.height /2) +3);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [path release];
            [arrow release];
        }
    } else {

        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Draw Decrement Button
            NSRect rect = [self rectForPart: NSScrollerDecrementLine];
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            //Add Notch
            [path appendBezierPathWithArcWithCenter: NSMakePoint(rect.origin.x - ((rect.size.height ) /2), (rect.origin.y  + ((rect.size.height ) /2) ))
                                             radius: (rect.size.height ) /2
                                         startAngle: 270
                                           endAngle: 90];

            //Add the rest of the points
            basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height);
            basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);

            //Add Points to Path
            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 90];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 90];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2);
            points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5);
            points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            //Create Devider Line
            [[[self theme] scrollerStroke] set];

            [NSBezierPath strokeLineFromPoint: NSMakePoint(rect.origin.x + rect.size.width -.5, rect.origin.y)
                                      toPoint: NSMakePoint(rect.origin.x + rect.size.width -.5, rect.origin.y + rect.size.height)];

            [path release];
            [arrow release];

        } else {

            NSRect rect = [self rectForPart: NSScrollerDecrementLine];

            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            [path appendBezierPathWithArcWithCenter: NSMakePoint(rect.origin.x + (rect.size.width -2) + ((rect.size.height ) /2), (rect.origin.y  + ((rect.size.height ) /2) ))
                                             radius: (rect.size.height ) /2
                                         startAngle: 90
                                           endAngle: 270];

            //Add the rest of the points
            basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
            basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);

            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 90];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 90];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2);
            points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5);
            points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [path release];
            [arrow release];
        }
    }
}

- (void)drawIncrementArrow:(BOOL)highlighted {
   NSRect bounds = [self bounds];
   if ( bounds.size.width < 40 && bounds.size.height < 40 )
      return; // don't draw something stupid if too tiny to show... happens often during initial sizing 

   BOOL isHoriz = ( bounds.size.width > bounds.size.height );

    if( ! isHoriz) {

        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Draw Increment Button
            NSRect rect = [self rectForPart: NSScrollerIncrementLine];

            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInRect: rect angle: 0];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInRect: rect angle: 0];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3);
            points[1] = NSMakePoint( (rect.size.width /2) +3.5, rect.origin.y + (rect.size.height /2) -3);
            points[2] = NSMakePoint( (rect.size.width /2) -3.5, rect.origin.y + (rect.size.height /2) -3);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [arrow release];
        } else {

            //Draw Decrement Button
            NSRect rect = [self rectForPart: NSScrollerIncrementLine];
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            //Add Notch
            [path appendBezierPathWithArcWithCenter: NSMakePoint((rect.size.width ) /2, (rect.origin.y  - ((rect.size.width ) /2) + 2))
                                             radius: (rect.size.width ) /2
                                         startAngle: 0
                                           endAngle: 180];

            //Add the rest of the points
            basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y);
            basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
            basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);

            //Add Points to Path
            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 0];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3);
            points[1] = NSMakePoint( (rect.size.width /2) +3.5, rect.origin.y + (rect.size.height /2) -3);
            points[2] = NSMakePoint( (rect.size.width /2) -3.5, rect.origin.y + (rect.size.height /2) -3);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [path release];
            [arrow release];
        }
    } else {

        if([arrowPosition isEqualToString: @"DoubleMax"]) {

            //Draw Increment Button
            NSRect rect = [self rectForPart: NSScrollerIncrementLine];

            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInRect: rect angle: 90];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInRect: rect angle: 90];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2);
            points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5);
            points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [arrow release];
        } else {

            //Draw Decrement Button
            NSRect rect = [self rectForPart: NSScrollerIncrementLine];
            NSBezierPath *path = [[NSBezierPath alloc] init];
            NSPoint basePoints[4];

            //Add Notch
            [path appendBezierPathWithArcWithCenter: NSMakePoint(rect.origin.x - (((rect.size.height ) /2) -2), (rect.origin.y  + ((rect.size.height ) /2) ))
                                             radius: (rect.size.height ) /2
                                         startAngle: 270
                                           endAngle: 90];

            //Add the rest of the points
            basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y);
            basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height);
            basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
            basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);

            //Add Points to Path
            [path appendBezierPathWithPoints: basePoints count: 4];

            //Fill Path
            if(!highlighted) {

                [[[self theme] scrollerArrowNormalGradient] drawInBezierPath: path angle: 0];
            } else {

                [[[self theme] scrollerArrowPushedGradient] drawInBezierPath: path angle: 0];
            }

            //Create Arrow Glyph
            NSBezierPath *arrow = [[NSBezierPath alloc] init];

            NSPoint points[3];
            points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2);
            points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5);
            points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5);

            [arrow appendBezierPathWithPoints: points count: 3];

            [[[self theme] scrollerStroke] set];
            [arrow fill];

            [path release];
            [arrow release];
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM