summaryrefslogtreecommitdiff
path: root/frontends/cocoa/BlackScroller.m
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/cocoa/BlackScroller.m')
-rw-r--r--frontends/cocoa/BlackScroller.m154
1 files changed, 154 insertions, 0 deletions
diff --git a/frontends/cocoa/BlackScroller.m b/frontends/cocoa/BlackScroller.m
new file mode 100644
index 000000000..2ee739f3a
--- /dev/null
+++ b/frontends/cocoa/BlackScroller.m
@@ -0,0 +1,154 @@
+/* Copyright (c) 1011 Sven Weidauer
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "BlackScroller.h"
+
+@implementation BlackScroller
+
+- (void) setFrame: (NSRect)frameRect
+{
+ [super setFrame: frameRect];
+ if (tag != 0) [self removeTrackingRect: tag];
+ tag = [self addTrackingRect: [self bounds] owner: self userData: NULL assumeInside: NO];
+}
+
+- (void) drawRect: (NSRect)dirtyRect
+{
+ [[NSColor clearColor] set];
+ [NSBezierPath fillRect: dirtyRect];
+
+ if (drawTrack) [self drawKnobSlotInRect: [self rectForPart: NSScrollerKnobSlot]
+ highlight: NO];
+ [self drawKnob];
+}
+
+- (void) drawKnobSlotInRect: (NSRect)slotRect highlight: (BOOL)flag
+{
+ slotRect = NSInsetRect( slotRect, 2, 2 );
+ slotRect = [self convertRectToBase: slotRect];
+ slotRect.origin.x = floor( slotRect.origin.x ) + 0.5;
+ slotRect.origin.y = floor( slotRect.origin.y ) + 0.5;
+ slotRect.size.width = floor( slotRect.size.width );
+ slotRect.size.height = floor( slotRect.size.height );
+ slotRect = [self convertRectFromBase: slotRect];
+
+ NSGradient *gradient = [[[NSGradient alloc] initWithColorsAndLocations:
+ [NSColor clearColor], 0.0,
+ [NSColor clearColor], 0.4,
+ [NSColor whiteColor], 1.0,
+ nil] autorelease];
+ [[NSColor whiteColor] set];
+ const float radius = 0.5 * ([self isHorizontal] ? NSHeight( slotRect ) : NSWidth( slotRect ));
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect: slotRect
+ xRadius: radius
+ yRadius: radius];
+ [gradient drawInBezierPath: path angle: [self isHorizontal] ? 90 : 0];
+
+ [path stroke];
+}
+
+
+- (NSUsableScrollerParts) usableParts
+{
+ return NSScrollerKnob | NSScrollerKnobSlot;
+}
+
+- (void) drawKnob
+{
+ NSRect rect = NSInsetRect( [self rectForPart: NSScrollerKnob], 2, 2 );
+
+ rect = [self convertRectToBase: rect];
+ rect.origin.x = floor( rect.origin.x ) + 0.5;
+ rect.origin.y = floor( rect.origin.y ) + 0.5;
+ rect.size.width = floor( rect.size.width );
+ rect.size.height = floor( rect.size.height );
+ rect = [self convertRectFromBase: rect];
+
+ [[NSColor colorWithDeviceWhite: 1.0 alpha: drawTrack ? 1.0 : 0.6] set];
+
+ const float radius = 0.5 * ([self isHorizontal] ? NSHeight( rect ) : NSWidth( rect ));
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect: rect
+ xRadius: radius
+ yRadius: radius];
+ [path fill];
+ [path stroke];
+}
+
+- (NSRect) rectForPart: (NSScrollerPart)partCode
+{
+ const bool horizontal = [self isHorizontal];
+
+ NSRect rect = horizontal ? NSInsetRect( [self bounds], 4, 0 ) : NSInsetRect( [self bounds], 0, 4 );
+
+ switch (partCode) {
+ case NSScrollerKnobSlot:
+ return rect;
+
+ case NSScrollerKnob: {
+ const CGFloat len = horizontal ? NSWidth( rect ) : NSHeight( rect );
+ CGFloat knobLen = [self knobProportion] * len;
+ const CGFloat minKnobLen = horizontal ? NSHeight( rect ) : NSWidth( rect );
+ if (knobLen < minKnobLen) knobLen = minKnobLen;
+
+ const CGFloat start = [self doubleValue] * (len - knobLen);
+
+ if (horizontal) {
+ rect.origin.x += start;
+ rect.size.width = knobLen;
+ } else {
+ rect.origin.y += start;
+ rect.size.height = knobLen;
+ }
+
+ return rect;
+ }
+
+ default:
+ return [super rectForPart: partCode];
+ }
+}
+
+- (BOOL) isOpaque
+{
+ return NO;
+}
+
+- (BOOL) isHorizontal
+{
+ NSRect bounds = [self bounds];
+ return NSWidth( bounds ) > NSHeight( bounds );
+}
+
+- (void) mouseEntered: (NSEvent *)theEvent
+{
+ drawTrack = YES;
+ [self setNeedsDisplay: YES];
+}
+
+- (void) mouseExited: (NSEvent *)theEvent
+{
+ drawTrack = NO;
+ [self setNeedsDisplay: YES];
+}
+
+@end