From 2ba97ae0dbd01a4f46c543ae025249e5349e0585 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 5 Jun 2017 11:20:56 +0200 Subject: Reformat code using clang-format. --- frontends/cocoa/.clang-format | 5 + frontends/cocoa/ArrowBox.m | 211 +- frontends/cocoa/ArrowWindow.m | 246 +- frontends/cocoa/BlackScroller.m | 178 +- frontends/cocoa/BookmarksController.m | 178 +- frontends/cocoa/BrowserView.m | 835 ++--- frontends/cocoa/BrowserViewController.m | 447 ++- frontends/cocoa/BrowserWindow.m | 4 +- frontends/cocoa/BrowserWindowController.m | 275 +- frontends/cocoa/DownloadWindowController.m | 465 +-- frontends/cocoa/FormSelectMenu.m | 57 +- frontends/cocoa/HistoryView.m | 153 +- frontends/cocoa/HistoryWindowController.m | 15 +- frontends/cocoa/LocalHistoryController.m | 143 +- frontends/cocoa/NetSurfAppDelegate.m | 228 +- frontends/cocoa/NetsurfApp.m | 299 +- .../PSMTabBarControl/NSBezierPath_AMShading.m | 181 +- .../cocoa/PSMTabBarControl/NSString_AITruncation.m | 26 +- .../PSMTabBarControl/PSMOverflowPopUpButton.m | 201 +- .../cocoa/PSMTabBarControl/PSMProgressIndicator.m | 27 +- .../cocoa/PSMTabBarControl/PSMRolloverButton.m | 201 +- frontends/cocoa/PSMTabBarControl/PSMTabBarCell.m | 669 ++-- .../cocoa/PSMTabBarControl/PSMTabBarControl.m | 3361 ++++++++++---------- .../cocoa/PSMTabBarControl/PSMTabBarController.m | 911 +++--- .../cocoa/PSMTabBarControl/PSMTabDragAssistant.m | 1424 +++++---- frontends/cocoa/PSMTabBarControl/PSMTabDragView.m | 56 +- .../cocoa/PSMTabBarControl/PSMTabDragWindow.m | 49 +- .../PSMTabBarControl/PSMTabDragWindowController.m | 149 +- .../cocoa/PSMTabBarControl/PSMUnifiedTabStyle.m | 879 ++--- frontends/cocoa/PreferencesWindowController.m | 27 +- frontends/cocoa/ScrollableView.m | 56 +- frontends/cocoa/SearchWindowController.m | 94 +- frontends/cocoa/Tree.m | 122 +- frontends/cocoa/TreeView.m | 190 +- frontends/cocoa/URLFieldCell.m | 249 +- frontends/cocoa/apple_image.m | 317 +- frontends/cocoa/bitmap.m | 285 +- frontends/cocoa/desktop-tree.m | 402 ++- frontends/cocoa/fetch.m | 112 +- frontends/cocoa/font.m | 333 +- frontends/cocoa/gui.m | 340 +- frontends/cocoa/plotter.m | 468 +-- frontends/cocoa/schedule.m | 68 +- frontends/cocoa/selection.m | 83 +- 44 files changed, 7670 insertions(+), 7349 deletions(-) create mode 100644 frontends/cocoa/.clang-format (limited to 'frontends/cocoa') diff --git a/frontends/cocoa/.clang-format b/frontends/cocoa/.clang-format new file mode 100644 index 000000000..1b3e2b921 --- /dev/null +++ b/frontends/cocoa/.clang-format @@ -0,0 +1,5 @@ +--- +Language: ObjC +BasedOnStyle: WebKit +PointerAlignment: Right +SortIncludes: false diff --git a/frontends/cocoa/ArrowBox.m b/frontends/cocoa/ArrowBox.m index 3eb7411a2..258a58cda 100644 --- a/frontends/cocoa/ArrowBox.m +++ b/frontends/cocoa/ArrowBox.m @@ -30,134 +30,131 @@ @synthesize arrowEdge; @synthesize cornerRadius; -- (void) setArrowEdge: (ArrowEdge)newEdge +- (void)setArrowEdge:(ArrowEdge)newEdge { - if (arrowEdge == newEdge) { - return; - } + if (arrowEdge == newEdge) { + return; + } - arrowEdge = newEdge; + arrowEdge = newEdge; - [self setNeedsDisplay: YES]; - updateShadow = YES; + [self setNeedsDisplay:YES]; + updateShadow = YES; } - -- (void) setArrowSize: (CGFloat)newSize +- (void)setArrowSize:(CGFloat)newSize { - arrowSize = newSize; - [self setNeedsDisplay: YES]; - updateShadow = YES; + arrowSize = newSize; + [self setNeedsDisplay:YES]; + updateShadow = YES; } - -- (void) setCornerRadius: (CGFloat)newRadius +- (void)setCornerRadius:(CGFloat)newRadius { - cornerRadius = newRadius; - [self setNeedsDisplay: YES]; - updateShadow = YES; + cornerRadius = newRadius; + [self setNeedsDisplay:YES]; + updateShadow = YES; } -- (void) setArrowPosition: (CGFloat)newPosition +- (void)setArrowPosition:(CGFloat)newPosition { - arrowPosition = newPosition; + arrowPosition = newPosition; - [self setNeedsDisplay: YES]; - updateShadow = YES; + [self setNeedsDisplay:YES]; + updateShadow = YES; } - - (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { - arrowPosition = 50; - cornerRadius = 10; - arrowSize = 15; - } - return self; + self = [super initWithFrame:frame]; + if (self) { + arrowPosition = 50; + cornerRadius = 10; + arrowSize = 15; + } + return self; } - (void)drawRect:(NSRect)dirtyRect { - [[NSColor clearColor] set]; - [NSBezierPath fillRect: dirtyRect]; - - NSBezierPath *path = [NSBezierPath bezierPath]; - - NSRect bounds = [self.window convertRectToScreen: NSInsetRect( [self bounds], 2, 2 )]; - bounds.origin.x = floor( bounds.origin.x ); - bounds.origin.y = floor( bounds.origin.y ); - bounds.size.width = floor( bounds.size.width ); - bounds.size.height = floor( bounds.size.height ); - bounds = [self.window convertRectFromScreen: bounds]; - - const CGFloat right = bounds.size.width - arrowSize; - const CGFloat top = bounds.size.height - arrowSize; - const CGFloat left = arrowSize; - const CGFloat bottom = arrowSize; - - [path setLineJoinStyle:NSRoundLineJoinStyle]; - - [path moveToPoint: NSMakePoint( right - cornerRadius, top )]; - - if (arrowEdge == ArrowTopEdge) { - [path lineToPoint: NSMakePoint( arrowPosition + arrowSize, top )]; - [path lineToPoint: NSMakePoint( arrowPosition, top + arrowSize )]; - [path lineToPoint: NSMakePoint( arrowPosition - arrowSize, top )]; - } - - [path appendBezierPathWithArcFromPoint: NSMakePoint( left, top ) - toPoint: NSMakePoint( left, top - cornerRadius ) - radius: cornerRadius]; - - if (arrowEdge == ArrowLeftEdge) { - [path lineToPoint: NSMakePoint( left, bottom + arrowPosition + arrowSize )]; - [path lineToPoint: NSMakePoint( left - arrowSize, bottom + arrowPosition )]; - [path lineToPoint: NSMakePoint( left, bottom + arrowPosition - arrowSize )]; - } - - [path appendBezierPathWithArcFromPoint: NSMakePoint( left, bottom ) - toPoint: NSMakePoint( left + cornerRadius, bottom ) - radius: cornerRadius]; - - if (arrowEdge == ArrowBottomEdge) { - [path lineToPoint: NSMakePoint( arrowPosition - arrowSize, bottom )]; - [path lineToPoint: NSMakePoint( arrowPosition, bottom - arrowSize )]; - [path lineToPoint: NSMakePoint( arrowPosition + arrowSize, bottom )]; - } - - [path appendBezierPathWithArcFromPoint: NSMakePoint( right, bottom ) - toPoint: NSMakePoint( right, bottom + cornerRadius ) - radius: cornerRadius]; - - if (arrowEdge == ArrowRightEdge) { - [path lineToPoint: NSMakePoint( right, bottom + arrowPosition - arrowSize )]; - [path lineToPoint: NSMakePoint( right + arrowSize, bottom + arrowPosition )]; - [path lineToPoint: NSMakePoint( right, bottom + arrowPosition + arrowSize )]; - } - - [path appendBezierPathWithArcFromPoint: NSMakePoint( right, top ) - toPoint: NSMakePoint( right - cornerRadius, top ) - radius: cornerRadius]; - [path closePath]; - - [[NSColor colorWithDeviceWhite: 1.0 alpha: 0.4] set]; - [[NSColor colorWithDeviceWhite: 0.0 alpha: 0.75] setFill]; - - NSAffineTransform *transform = [NSAffineTransform transform]; - [transform translateXBy: bounds.origin.x yBy: bounds.origin.y]; - [transform concat]; - - [path setLineWidth: 2.0]; - [path fill]; - [path stroke]; - - if (updateShadow) { - [[self window] invalidateShadow]; - [[self window] update]; - updateShadow = NO; - } + [[NSColor clearColor] set]; + [NSBezierPath fillRect:dirtyRect]; + + NSBezierPath *path = [NSBezierPath bezierPath]; + + NSRect bounds = [self.window convertRectToScreen:NSInsetRect([self bounds], 2, 2)]; + bounds.origin.x = floor(bounds.origin.x); + bounds.origin.y = floor(bounds.origin.y); + bounds.size.width = floor(bounds.size.width); + bounds.size.height = floor(bounds.size.height); + bounds = [self.window convertRectFromScreen:bounds]; + + const CGFloat right = bounds.size.width - arrowSize; + const CGFloat top = bounds.size.height - arrowSize; + const CGFloat left = arrowSize; + const CGFloat bottom = arrowSize; + + [path setLineJoinStyle:NSRoundLineJoinStyle]; + + [path moveToPoint:NSMakePoint(right - cornerRadius, top)]; + + if (arrowEdge == ArrowTopEdge) { + [path lineToPoint:NSMakePoint(arrowPosition + arrowSize, top)]; + [path lineToPoint:NSMakePoint(arrowPosition, top + arrowSize)]; + [path lineToPoint:NSMakePoint(arrowPosition - arrowSize, top)]; + } + + [path appendBezierPathWithArcFromPoint:NSMakePoint(left, top) + toPoint:NSMakePoint(left, top - cornerRadius) + radius:cornerRadius]; + + if (arrowEdge == ArrowLeftEdge) { + [path lineToPoint:NSMakePoint(left, bottom + arrowPosition + arrowSize)]; + [path lineToPoint:NSMakePoint(left - arrowSize, bottom + arrowPosition)]; + [path lineToPoint:NSMakePoint(left, bottom + arrowPosition - arrowSize)]; + } + + [path appendBezierPathWithArcFromPoint:NSMakePoint(left, bottom) + toPoint:NSMakePoint(left + cornerRadius, bottom) + radius:cornerRadius]; + + if (arrowEdge == ArrowBottomEdge) { + [path lineToPoint:NSMakePoint(arrowPosition - arrowSize, bottom)]; + [path lineToPoint:NSMakePoint(arrowPosition, bottom - arrowSize)]; + [path lineToPoint:NSMakePoint(arrowPosition + arrowSize, bottom)]; + } + + [path appendBezierPathWithArcFromPoint:NSMakePoint(right, bottom) + toPoint:NSMakePoint(right, bottom + cornerRadius) + radius:cornerRadius]; + + if (arrowEdge == ArrowRightEdge) { + [path lineToPoint:NSMakePoint(right, bottom + arrowPosition - arrowSize)]; + [path lineToPoint:NSMakePoint(right + arrowSize, bottom + arrowPosition)]; + [path lineToPoint:NSMakePoint(right, bottom + arrowPosition + arrowSize)]; + } + + [path appendBezierPathWithArcFromPoint:NSMakePoint(right, top) + toPoint:NSMakePoint(right - cornerRadius, top) + radius:cornerRadius]; + [path closePath]; + + [[NSColor colorWithDeviceWhite:1.0 alpha:0.4] set]; + [[NSColor colorWithDeviceWhite:0.0 alpha:0.75] setFill]; + + NSAffineTransform *transform = [NSAffineTransform transform]; + [transform translateXBy:bounds.origin.x yBy:bounds.origin.y]; + [transform concat]; + + [path setLineWidth:2.0]; + [path fill]; + [path stroke]; + + if (updateShadow) { + [[self window] invalidateShadow]; + [[self window] update]; + updateShadow = NO; + } } @end diff --git a/frontends/cocoa/ArrowWindow.m b/frontends/cocoa/ArrowWindow.m index 84dbe1ef7..720e55e29 100644 --- a/frontends/cocoa/ArrowWindow.m +++ b/frontends/cocoa/ArrowWindow.m @@ -28,211 +28,213 @@ @synthesize acceptsKey; -- (id) initWithContentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)aStyle backing: (NSBackingStoreType)bufferingType defer: (BOOL)flag +- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag { - if ((self = [super initWithContentRect: contentRect styleMask: NSWindowStyleMaskBorderless backing: bufferingType defer: flag]) == nil) { - return nil; - } + if ((self = [super initWithContentRect:contentRect styleMask:NSWindowStyleMaskBorderless backing:bufferingType defer:flag]) == nil) { + return nil; + } - [self setBackgroundColor: [NSColor clearColor]]; - [self setOpaque: NO]; - [self setHasShadow: YES]; + [self setBackgroundColor:[NSColor clearColor]]; + [self setOpaque:NO]; + [self setHasShadow:YES]; - return self; + return self; } -- (void) setContentView: (NSView *)aView +- (void)setContentView:(NSView *)aView { - if (aView == content) return; + if (aView == content) + return; - [content removeFromSuperview]; - content = aView; + [content removeFromSuperview]; + content = aView; - if (content == nil) return; + if (content == nil) + return; - if (box == nil) { - box = [[ArrowBox alloc] initWithFrame: NSZeroRect]; - [box setArrowEdge: ArrowTopEdge]; - [super setContentView: box]; - } + if (box == nil) { + box = [[ArrowBox alloc] initWithFrame:NSZeroRect]; + [box setArrowEdge:ArrowTopEdge]; + [super setContentView:box]; + } - [box addSubview: content]; + [box addSubview:content]; - NSRect frame = [self contentRectForFrameRect: [self frame]]; - frame.origin = [self convertRectFromScreen: (CGRect){.origin = frame.origin}].origin; - frame = [box convertRect: frame fromView: nil]; + NSRect frame = [self contentRectForFrameRect:[self frame]]; + frame.origin = [self convertRectFromScreen:(CGRect){.origin = frame.origin }].origin; + frame = [box convertRect:frame fromView:nil]; - [content setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; - [content setFrame: frame]; + [content setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [content setFrame:frame]; } -- (void) setContentSize: (NSSize)aSize +- (void)setContentSize:(NSSize)aSize { - NSRect frame = [content frame]; - frame.size = aSize; + NSRect frame = [content frame]; + frame.size = aSize; - frame = [box convertRect: frame toView: nil]; - frame.origin = [self convertRectToScreen: (CGRect){.origin = frame.origin}].origin; - frame = [self frameRectForContentRect: frame]; + frame = [box convertRect:frame toView:nil]; + frame.origin = [self convertRectToScreen:(CGRect){.origin = frame.origin }].origin; + frame = [self frameRectForContentRect:frame]; - [self setFrame: frame display: YES]; + [self setFrame:frame display:YES]; } static const CGFloat padding = 0; -- (NSRect) contentRectForFrameRect: (NSRect)frameRect +- (NSRect)contentRectForFrameRect:(NSRect)frameRect { - const CGFloat arrowSize = [box arrowSize]; - const CGFloat offset = 2 * (padding + arrowSize ); + const CGFloat arrowSize = [box arrowSize]; + const CGFloat offset = 2 * (padding + arrowSize); - return NSInsetRect( frameRect, offset, offset ); + return NSInsetRect(frameRect, offset, offset); } -- (NSRect) frameRectForContentRect: (NSRect)contentRect +- (NSRect)frameRectForContentRect:(NSRect)contentRect { - const CGFloat arrowSize = [box arrowSize]; - const CGFloat offset = -2 * (padding + arrowSize ); + const CGFloat arrowSize = [box arrowSize]; + const CGFloat offset = -2 * (padding + arrowSize); - return NSInsetRect( contentRect, offset, offset ); + return NSInsetRect(contentRect, offset, offset); } -+ (NSRect) frameRectForContentRect: (NSRect)cRect styleMask: (NSWindowStyleMask)aStyle ++ (NSRect)frameRectForContentRect:(NSRect)cRect styleMask:(NSWindowStyleMask)aStyle { - const CGFloat DefaultArrowSize = 15; - const CGFloat offset = -2 * (padding + DefaultArrowSize); + const CGFloat DefaultArrowSize = 15; + const CGFloat offset = -2 * (padding + DefaultArrowSize); - return NSInsetRect( cRect, offset, offset ); + return NSInsetRect(cRect, offset, offset); } -- (BOOL) canBecomeKeyWindow +- (BOOL)canBecomeKeyWindow { - return acceptsKey; + return acceptsKey; } -- (void) moveToPoint: (NSPoint) screenPoint +- (void)moveToPoint:(NSPoint)screenPoint { - switch ([box arrowEdge]) { - case ArrowNone: - screenPoint.x -= [box arrowSize]; - screenPoint.y += [box arrowSize]; - break; + switch ([box arrowEdge]) { + case ArrowNone: + screenPoint.x -= [box arrowSize]; + screenPoint.y += [box arrowSize]; + break; - case ArrowTopEdge: - screenPoint.x -= [box arrowPosition]; - break; + case ArrowTopEdge: + screenPoint.x -= [box arrowPosition]; + break; - case ArrowBottomEdge: - screenPoint.x -= [box arrowPosition]; - screenPoint.y += NSHeight( [self frame] ); - break; + case ArrowBottomEdge: + screenPoint.x -= [box arrowPosition]; + screenPoint.y += NSHeight([self frame]); + break; - case ArrowLeftEdge: - screenPoint.y += NSHeight( [self frame] ) - [box arrowPosition] - [box arrowSize]; - break; + case ArrowLeftEdge: + screenPoint.y += NSHeight([self frame]) - [box arrowPosition] - [box arrowSize]; + break; - case ArrowRightEdge: - screenPoint.x -= NSWidth( [self frame] ); - screenPoint.y += NSHeight( [self frame] ) - [box arrowPosition] - [box arrowSize]; - break; - } + case ArrowRightEdge: + screenPoint.x -= NSWidth([self frame]); + screenPoint.y += NSHeight([self frame]) - [box arrowPosition] - [box arrowSize]; + break; + } - [self setFrameTopLeftPoint: screenPoint]; + [self setFrameTopLeftPoint:screenPoint]; } -static NSRect ScreenRectForView( NSView *view ) +static NSRect ScreenRectForView(NSView *view) { - NSRect viewRect = [view bounds]; // in View coordinate system - viewRect = [view convertRect: viewRect toView: nil]; // translate to window coordinates - viewRect.origin = [[view window] convertRectToScreen: (CGRect){.origin = viewRect.origin}].origin; // translate to screen coordinates - return viewRect; + NSRect viewRect = [view bounds]; // in View coordinate system + viewRect = [view convertRect:viewRect toView:nil]; // translate to window coordinates + viewRect.origin = [[view window] convertRectToScreen:(CGRect){.origin = viewRect.origin }].origin; // translate to screen coordinates + return viewRect; } -- (void) attachToView: (NSView *) view +- (void)attachToView:(NSView *)view { - if (nil != attachedWindow) [self detach]; + if (nil != attachedWindow) + [self detach]; - NSRect viewRect = ScreenRectForView( view ); - NSPoint arrowPoint; + NSRect viewRect = ScreenRectForView(view); + NSPoint arrowPoint; - switch ([box arrowEdge]) { - case ArrowLeftEdge: - arrowPoint = NSMakePoint( NSMaxX( viewRect ), - NSMidY( viewRect ) ); - break; + switch ([box arrowEdge]) { + case ArrowLeftEdge: + arrowPoint = NSMakePoint(NSMaxX(viewRect), + NSMidY(viewRect)); + break; - case ArrowBottomEdge: - arrowPoint = NSMakePoint( NSMidX( viewRect ), - NSMaxY( viewRect ) ); - break; + case ArrowBottomEdge: + arrowPoint = NSMakePoint(NSMidX(viewRect), + NSMaxY(viewRect)); + break; - case ArrowRightEdge: - arrowPoint = NSMakePoint( NSMinX( viewRect ), - NSMidY( viewRect ) ); - break; + case ArrowRightEdge: + arrowPoint = NSMakePoint(NSMinX(viewRect), + NSMidY(viewRect)); + break; - case ArrowNone: - case ArrowTopEdge: - default: - arrowPoint = NSMakePoint( NSMidX( viewRect ), - NSMinY( viewRect ) ); - break; - - } - attachedWindow = [view window]; - [self moveToPoint: arrowPoint]; - [attachedWindow addChildWindow: self ordered: NSWindowAbove]; + case ArrowNone: + case ArrowTopEdge: + default: + arrowPoint = NSMakePoint(NSMidX(viewRect), + NSMinY(viewRect)); + break; + } + attachedWindow = [view window]; + [self moveToPoint:arrowPoint]; + [attachedWindow addChildWindow:self ordered:NSWindowAbove]; } -- (void) detach +- (void)detach { - [attachedWindow removeChildWindow: self]; - [self close]; - attachedWindow = nil; + [attachedWindow removeChildWindow:self]; + [self close]; + attachedWindow = nil; } //MARK: - //MARK: Properties -- (void) setArrowPosition: (CGFloat) newPosition +- (void)setArrowPosition:(CGFloat)newPosition { - [box setArrowPosition: newPosition]; + [box setArrowPosition:newPosition]; } -- (CGFloat) arrowPosition +- (CGFloat)arrowPosition { - return [box arrowPosition]; + return [box arrowPosition]; } -- (void) setArrowSize: (CGFloat)newSize +- (void)setArrowSize:(CGFloat)newSize { - NSRect contentRect = [self contentRectForFrameRect: [self frame]]; - [box setArrowSize: newSize]; - [self setFrame: [self frameRectForContentRect: contentRect] display: [self isVisible]]; + NSRect contentRect = [self contentRectForFrameRect:[self frame]]; + [box setArrowSize:newSize]; + [self setFrame:[self frameRectForContentRect:contentRect] display:[self isVisible]]; } -- (CGFloat) arrowSize +- (CGFloat)arrowSize { - return [box arrowSize]; + return [box arrowSize]; } -- (void) setArrowEdge: (ArrowEdge) newEdge +- (void)setArrowEdge:(ArrowEdge)newEdge { - [box setArrowEdge: newEdge]; + [box setArrowEdge:newEdge]; } -- (ArrowEdge) arrowEdge +- (ArrowEdge)arrowEdge { - return [box arrowEdge]; + return [box arrowEdge]; } -- (void) setCornerRadius: (CGFloat)newRadius +- (void)setCornerRadius:(CGFloat)newRadius { - [box setCornerRadius: newRadius]; + [box setCornerRadius:newRadius]; } -- (CGFloat) cornerRadius +- (CGFloat)cornerRadius { - return [box cornerRadius]; + return [box cornerRadius]; } @end diff --git a/frontends/cocoa/BlackScroller.m b/frontends/cocoa/BlackScroller.m index 025e3a955..df15e916f 100644 --- a/frontends/cocoa/BlackScroller.m +++ b/frontends/cocoa/BlackScroller.m @@ -25,130 +25,132 @@ @implementation BlackScroller -- (void) setFrame: (NSRect)frameRect +- (void)setFrame:(NSRect)frameRect { - [super setFrame: frameRect]; - if (tag != 0) [self removeTrackingRect: tag]; - tag = [self addTrackingRect: [self bounds] owner: self userData: NULL assumeInside: NO]; + [super setFrame:frameRect]; + if (tag != 0) + [self removeTrackingRect:tag]; + tag = [self addTrackingRect:[self bounds] owner:self userData:NULL assumeInside:NO]; } -- (void) drawRect: (NSRect)dirtyRect +- (void)drawRect:(NSRect)dirtyRect { - [[NSColor clearColor] set]; - [NSBezierPath fillRect: dirtyRect]; + [[NSColor clearColor] set]; + [NSBezierPath fillRect:dirtyRect]; - if (drawTrack) [self drawKnobSlotInRect: [self rectForPart: NSScrollerKnobSlot] - highlight: NO]; - [self drawKnob]; + if (drawTrack) + [self drawKnobSlotInRect:[self rectForPart:NSScrollerKnobSlot] + highlight:NO]; + [self drawKnob]; } -- (void) drawKnobSlotInRect: (NSRect)slotRect highlight: (BOOL)flag +- (void)drawKnobSlotInRect:(NSRect)slotRect highlight:(BOOL)flag { - slotRect = NSInsetRect( slotRect, 2, 2 ); - slotRect = [self.window convertRectToScreen: 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.window convertRectFromScreen: slotRect]; - - NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations: - [NSColor clearColor], 0.0, - [NSColor clearColor], 0.4, - [NSColor whiteColor], 1.0, - nil]; - [[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]; + slotRect = NSInsetRect(slotRect, 2, 2); + slotRect = [self.window convertRectToScreen: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.window convertRectFromScreen:slotRect]; + + NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations: + [NSColor clearColor], 0.0, + [NSColor clearColor], 0.4, + [NSColor whiteColor], 1.0, + nil]; + [[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 +- (NSUsableScrollerParts)usableParts { - return NSScrollerKnob | NSScrollerKnobSlot; + return NSScrollerKnob | NSScrollerKnobSlot; } -- (void) drawKnob +- (void)drawKnob { - NSRect rect = NSInsetRect( [self rectForPart: NSScrollerKnob], 2, 2 ); - - rect = [self.window convertRectToScreen: 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.window convertRectFromScreen: 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 rect = NSInsetRect([self rectForPart:NSScrollerKnob], 2, 2); + + rect = [self.window convertRectToScreen: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.window convertRectFromScreen: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 +- (NSRect)rectForPart:(NSScrollerPart)partCode { - const bool horizontal = [self isHorizontal]; - - NSRect rect = horizontal ? NSInsetRect( [self bounds], 4, 0 ) : NSInsetRect( [self bounds], 0, 4 ); + const bool horizontal = [self isHorizontal]; - switch (partCode) { - case NSScrollerKnobSlot: - return rect; + NSRect rect = horizontal ? NSInsetRect([self bounds], 4, 0) : NSInsetRect([self bounds], 0, 4); - 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; + switch (partCode) { + case NSScrollerKnobSlot: + return rect; - const CGFloat start = [self doubleValue] * (len - knobLen); + 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; - if (horizontal) { - rect.origin.x += start; - rect.size.width = knobLen; - } else { - rect.origin.y += start; - rect.size.height = knobLen; - } + const CGFloat start = [self doubleValue] * (len - knobLen); - return rect; + if (horizontal) { + rect.origin.x += start; + rect.size.width = knobLen; + } else { + rect.origin.y += start; + rect.size.height = knobLen; } - default: - return [super rectForPart: partCode]; - } + return rect; + } + + default: + return [super rectForPart:partCode]; + } } -- (BOOL) isOpaque +- (BOOL)isOpaque { - return NO; + return NO; } -- (BOOL) isHorizontal +- (BOOL)isHorizontal { - NSRect bounds = [self bounds]; - return NSWidth( bounds ) > NSHeight( bounds ); + NSRect bounds = [self bounds]; + return NSWidth(bounds) > NSHeight(bounds); } -- (void) mouseEntered: (NSEvent *)theEvent +- (void)mouseEntered:(NSEvent *)theEvent { - drawTrack = YES; - [self setNeedsDisplay: YES]; + drawTrack = YES; + [self setNeedsDisplay:YES]; } -- (void) mouseExited: (NSEvent *)theEvent +- (void)mouseExited:(NSEvent *)theEvent { - drawTrack = NO; - [self setNeedsDisplay: YES]; + drawTrack = NO; + [self setNeedsDisplay:YES]; } @end diff --git a/frontends/cocoa/BookmarksController.m b/frontends/cocoa/BookmarksController.m index c8a23cb8d..f2358cd53 100644 --- a/frontends/cocoa/BookmarksController.m +++ b/frontends/cocoa/BookmarksController.m @@ -33,10 +33,9 @@ #import "cocoa/BrowserViewController.h" #import "cocoa/gui.h" - @interface BookmarksController () -- (void) noteAppWillTerminate: (NSNotification *) note; -- (void) save; +- (void)noteAppWillTerminate:(NSNotification *)note; +- (void)save; @end @implementation BookmarksController @@ -44,52 +43,52 @@ @synthesize defaultMenu; @synthesize view; -static const char *cocoa_hotlist_path( void ) +static const char *cocoa_hotlist_path(void) { - NSString *path = [[NSUserDefaults standardUserDefaults] - stringForKey: kHotlistFileOption]; - return [path UTF8String]; + NSString *path = [[NSUserDefaults standardUserDefaults] + stringForKey:kHotlistFileOption]; + return [path UTF8String]; } - (id)init { - if ((self = [super initWithWindowNibName: @"BookmarksWindow"]) == nil) { - return nil; - } - tree_hotlist_path = cocoa_hotlist_path(); - tree = [[Tree alloc] initWithFlags: TREE_HOTLIST]; - nodeForMenu = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, - NSNonOwnedPointerMapValueCallBacks, - 0); - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(noteAppWillTerminate:) - name:NSApplicationWillTerminateNotification - object:NSApp]; - - return self; + if ((self = [super initWithWindowNibName:@"BookmarksWindow"]) == nil) { + return nil; + } + tree_hotlist_path = cocoa_hotlist_path(); + tree = [[Tree alloc] initWithFlags:TREE_HOTLIST]; + nodeForMenu = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, + NSNonOwnedPointerMapValueCallBacks, + 0); + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(noteAppWillTerminate:) + name:NSApplicationWillTerminateNotification + object:NSApp]; + + return self; } -- (void) noteAppWillTerminate: (NSNotification *)note +- (void)noteAppWillTerminate:(NSNotification *)note { - [self save]; + [self save]; } -- (void) save +- (void)save { - hotlist_export( cocoa_hotlist_path(), NULL ); + hotlist_export(cocoa_hotlist_path(), NULL); } -- (void) dealloc +- (void)dealloc { - [self setView: nil]; - NSFreeMapTable( nodeForMenu ); + [self setView:nil]; + NSFreeMapTable(nodeForMenu); - [[NSNotificationCenter defaultCenter] removeObserver: self]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void) menuNeedsUpdate: (NSMenu *)menu +- (void)menuNeedsUpdate:(NSMenu *)menu { #if 0 for (NSMenuItem *item in [menu itemArray]) { @@ -134,90 +133,89 @@ static const char *cocoa_hotlist_path( void ) #endif } -- (IBAction) openBookmarkURL: (id)sender +- (IBAction)openBookmarkURL:(id)sender { - const char *urltxt = [[sender representedObject] UTF8String]; - NSParameterAssert( urltxt != NULL ); - - nsurl *url; - nserror error; - - error = nsurl_create(urltxt, &url); - if (error == NSERROR_OK) { - BrowserViewController *tab = [(NetSurfApp *)NSApp frontTab]; - if (tab != nil) { - error = browser_window_navigate([tab browser], - url, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - } else { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - } - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); + const char *urltxt = [[sender representedObject] UTF8String]; + NSParameterAssert(urltxt != NULL); + + nsurl *url; + nserror error; + + error = nsurl_create(urltxt, &url); + if (error == NSERROR_OK) { + BrowserViewController *tab = [(NetSurfApp *)NSApp frontTab]; + if (tab != nil) { + error = browser_window_navigate([tab browser], + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + } else { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); } + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (IBAction) addBookmark: (id)sender +- (IBAction)addBookmark:(id)sender { - struct browser_window *bw = [[(NetSurfApp *)NSApp frontTab] browser]; - if (bw != NULL) { - hotlist_add_url(browser_window_get_url(bw)); - } + struct browser_window *bw = [[(NetSurfApp *)NSApp frontTab] browser]; + if (bw != NULL) { + hotlist_add_url(browser_window_get_url(bw)); + } } -- (BOOL) validateUserInterfaceItem: (id)item +- (BOOL)validateUserInterfaceItem:(id)item { - SEL action = [item action]; + SEL action = [item action]; - if (action == @selector( addBookmark: )) { - return [(NetSurfApp *)NSApp frontTab] != nil; - } + if (action == @selector(addBookmark:)) { + return [(NetSurfApp *)NSApp frontTab] != nil; + } - return YES; + return YES; } -- (void) windowDidLoad +- (void)windowDidLoad { - hotlist_expand(false); - hotlist_contract(true); + hotlist_expand(false); + hotlist_contract(true); - [view setTree: tree]; + [view setTree:tree]; } - -+ (void) initialize ++ (void)initialize { - [[NSUserDefaults standardUserDefaults] - registerDefaults: - [NSDictionary - dictionaryWithObjectsAndKeys:cocoa_get_user_path( @"Bookmarks.html" ), - kHotlistFileOption, - nil]]; + [[NSUserDefaults standardUserDefaults] + registerDefaults: + [NSDictionary + dictionaryWithObjectsAndKeys:cocoa_get_user_path(@"Bookmarks.html"), + kHotlistFileOption, + nil]]; } -- (IBAction) editSelected: (id)sender +- (IBAction)editSelected:(id)sender { - hotlist_edit_selection(); + hotlist_edit_selection(); } -- (IBAction) deleteSelected: (id)sender +- (IBAction)deleteSelected:(id)sender { - hotlist_keypress(NS_KEY_DELETE_LEFT); + hotlist_keypress(NS_KEY_DELETE_LEFT); } -- (IBAction) addFolder: (id)sender +- (IBAction)addFolder:(id)sender { - hotlist_add_folder(NULL, false, 0); + hotlist_add_folder(NULL, false, 0); } @end diff --git a/frontends/cocoa/BrowserView.m b/frontends/cocoa/BrowserView.m index 31e74255d..c1cf9beb9 100644 --- a/frontends/cocoa/BrowserView.m +++ b/frontends/cocoa/BrowserView.m @@ -34,23 +34,22 @@ #import "cocoa/LocalHistoryController.h" #import "cocoa/BrowserWindowController.h" - @interface BrowserView () @property (readwrite, copy, nonatomic) NSString *markedText; -- (void) scrollHorizontal: (CGFloat) amount; -- (void) scrollVertical: (CGFloat) amount; -- (CGFloat) pageScroll; +- (void)scrollHorizontal:(CGFloat)amount; +- (void)scrollVertical:(CGFloat)amount; +- (CGFloat)pageScroll; -- (void) popUpContextMenuForEvent: (NSEvent *) event; +- (void)popUpContextMenuForEvent:(NSEvent *)event; -- (IBAction) cmOpenURLInTab: (id) sender; -- (IBAction) cmOpenURLInWindow: (id) sender; -- (IBAction) cmDownloadURL: (id) sender; +- (IBAction)cmOpenURLInTab:(id)sender; +- (IBAction)cmOpenURLInWindow:(id)sender; +- (IBAction)cmDownloadURL:(id)sender; -- (IBAction) cmLinkCopy: (id) sender; -- (IBAction) cmImageCopy: (id) sender; +- (IBAction)cmLinkCopy:(id)sender; +- (IBAction)cmImageCopy:(id)sender; @end @@ -63,83 +62,82 @@ static const CGFloat CaretWidth = 1.0; static const NSTimeInterval CaretBlinkTime = 0.8; -- (instancetype)initWithFrame: (NSRect) frame +- (instancetype)initWithFrame:(NSRect)frame { - if ((self = [super initWithFrame: frame]) == nil) { - return nil; - } + if ((self = [super initWithFrame:frame]) == nil) { + return nil; + } - [self registerForDraggedTypes: [NSArray arrayWithObjects: NSURLPboardType, @"public.url", nil]]; + [self registerForDraggedTypes:[NSArray arrayWithObjects:NSURLPboardType, @"public.url", nil]]; - return self; + return self; } -- (void) dealloc +- (void)dealloc { - [self setCaretTimer: nil]; - [self setMarkedText: nil]; + [self setCaretTimer:nil]; + [self setMarkedText:nil]; } -- (void) setCaretTimer: (NSTimer *)newTimer +- (void)setCaretTimer:(NSTimer *)newTimer { - if (newTimer != caretTimer) { - [caretTimer invalidate]; - caretTimer = newTimer; - } + if (newTimer != caretTimer) { + [caretTimer invalidate]; + caretTimer = newTimer; + } } -- (void) updateHistory +- (void)updateHistory { - [history redraw]; + [history redraw]; } -static inline NSRect cocoa_get_caret_rect( BrowserView *view ) +static inline NSRect cocoa_get_caret_rect(BrowserView *view) { - float bscale = browser_window_get_scale(view->browser); + float bscale = browser_window_get_scale(view->browser); - NSRect caretRect = { - .origin = NSMakePoint( view->caretPoint.x * bscale, view->caretPoint.y * bscale ), - .size = NSMakeSize( CaretWidth, view->caretHeight * bscale ) - }; + NSRect caretRect = { + .origin = NSMakePoint(view->caretPoint.x * bscale, view->caretPoint.y * bscale), + .size = NSMakeSize(CaretWidth, view->caretHeight * bscale) + }; - return caretRect; + return caretRect; } -- (void) removeCaret +- (void)removeCaret { - hasCaret = NO; - [self setNeedsDisplayInRect: cocoa_get_caret_rect( self )]; + hasCaret = NO; + [self setNeedsDisplayInRect:cocoa_get_caret_rect(self)]; - [self setCaretTimer: nil]; + [self setCaretTimer:nil]; } -- (void) addCaretAt: (NSPoint) point height: (CGFloat) height +- (void)addCaretAt:(NSPoint)point height:(CGFloat)height { - if (hasCaret) { - [self setNeedsDisplayInRect: cocoa_get_caret_rect( self )]; - } + if (hasCaret) { + [self setNeedsDisplayInRect:cocoa_get_caret_rect(self)]; + } - caretPoint = point; - caretHeight = height; - hasCaret = YES; - caretVisible = YES; + caretPoint = point; + caretHeight = height; + hasCaret = YES; + caretVisible = YES; - if (nil == caretTimer) { - [self setCaretTimer: [NSTimer scheduledTimerWithTimeInterval: CaretBlinkTime target: self selector: @selector(caretBlink:) userInfo: nil repeats: YES]]; - } else { - [caretTimer setFireDate: [NSDate dateWithTimeIntervalSinceNow: CaretBlinkTime]]; - } + if (nil == caretTimer) { + [self setCaretTimer:[NSTimer scheduledTimerWithTimeInterval:CaretBlinkTime target:self selector:@selector(caretBlink:) userInfo:nil repeats:YES]]; + } else { + [caretTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:CaretBlinkTime]]; + } - [self setNeedsDisplayInRect: cocoa_get_caret_rect( self )]; + [self setNeedsDisplayInRect:cocoa_get_caret_rect(self)]; } - -- (void) caretBlink: (NSTimer *)timer +- (void)caretBlink:(NSTimer *)timer { - if (hasCaret) { - caretVisible = !caretVisible; - [self setNeedsDisplayInRect: cocoa_get_caret_rect( self )]; - } + if (hasCaret) { + caretVisible = !caretVisible; + [self setNeedsDisplayInRect:cocoa_get_caret_rect(self)]; + } } - (void)drawRect:(NSRect)dirtyRect @@ -147,596 +145,605 @@ static inline NSRect cocoa_get_caret_rect( BrowserView *view ) @autoreleasepool { struct redraw_context ctx = { - .interactive = true, - .background_images = true, - .plot = &cocoa_plotters + .interactive = true, + .background_images = true, + .plot = &cocoa_plotters }; const NSRect *rects = NULL; NSInteger count = 0; - [self getRectsBeingDrawn: &rects count: &count]; + [self getRectsBeingDrawn:&rects count:&count]; for (NSInteger i = 0; i < count; i++) { - const struct rect clip = { - .x0 = cocoa_pt_to_px( NSMinX( rects[i] ) ), - .y0 = cocoa_pt_to_px( NSMinY( rects[i] ) ), - .x1 = cocoa_pt_to_px( NSMaxX( rects[i] ) ), - .y1 = cocoa_pt_to_px( NSMaxY( rects[i] ) ) - }; - - browser_window_redraw(browser, 0, 0, &clip, &ctx); + const struct rect clip = { + .x0 = cocoa_pt_to_px(NSMinX(rects[i])), + .y0 = cocoa_pt_to_px(NSMinY(rects[i])), + .x1 = cocoa_pt_to_px(NSMaxX(rects[i])), + .y1 = cocoa_pt_to_px(NSMaxY(rects[i])) + }; + + browser_window_redraw(browser, 0, 0, &clip, &ctx); } - NSRect caretRect = cocoa_get_caret_rect( self ); - if (hasCaret && caretVisible && [self needsToDrawRect: caretRect]) { - [[NSColor blackColor] set]; - [NSBezierPath fillRect: caretRect]; + NSRect caretRect = cocoa_get_caret_rect(self); + if (hasCaret && caretVisible && [self needsToDrawRect:caretRect]) { + [[NSColor blackColor] set]; + [NSBezierPath fillRect:caretRect]; } - } } -- (BOOL) isFlipped +- (BOOL)isFlipped { - return YES; + return YES; } -- (void) viewDidMoveToWindow +- (void)viewDidMoveToWindow { - NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: [self visibleRect] - options: NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect - owner: self - userInfo: nil]; - [self addTrackingArea: area]; + NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self visibleRect] + options:NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect + owner:self + userInfo:nil]; + [self addTrackingArea:area]; } -static browser_mouse_state cocoa_mouse_flags_for_event( NSEvent *evt ) +static browser_mouse_state cocoa_mouse_flags_for_event(NSEvent *evt) { - browser_mouse_state result = 0; - NSUInteger flags = [evt modifierFlags]; + browser_mouse_state result = 0; + NSUInteger flags = [evt modifierFlags]; - if (flags & NSEventModifierFlagShift) result |= BROWSER_MOUSE_MOD_1; - if (flags & NSEventModifierFlagOption) result |= BROWSER_MOUSE_MOD_2; + if (flags & NSEventModifierFlagShift) + result |= BROWSER_MOUSE_MOD_1; + if (flags & NSEventModifierFlagOption) + result |= BROWSER_MOUSE_MOD_2; - return result; + return result; } -- (NSPoint) convertMousePoint: (NSEvent *)event +- (NSPoint)convertMousePoint:(NSEvent *)event { - NSPoint location = [self convertPoint: [event locationInWindow] fromView: nil]; - float bscale = browser_window_get_scale(browser); + NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; + float bscale = browser_window_get_scale(browser); - location.x /= bscale; - location.y /= bscale; + location.x /= bscale; + location.y /= bscale; - location.x = cocoa_pt_to_px( location.x ); - location.y = cocoa_pt_to_px( location.y ); - return location; + location.x = cocoa_pt_to_px(location.x); + location.y = cocoa_pt_to_px(location.y); + return location; } -- (void) mouseDown: (NSEvent *)theEvent +- (void)mouseDown:(NSEvent *)theEvent { - if ([theEvent modifierFlags] & NSEventModifierFlagControl) { - [self popUpContextMenuForEvent: theEvent]; - return; - } + if ([theEvent modifierFlags] & NSEventModifierFlagControl) { + [self popUpContextMenuForEvent:theEvent]; + return; + } - dragStart = [self convertMousePoint: theEvent]; + dragStart = [self convertMousePoint:theEvent]; - browser_window_mouse_click(browser, - BROWSER_MOUSE_PRESS_1 | cocoa_mouse_flags_for_event( theEvent ), - dragStart.x, - dragStart.y ); + browser_window_mouse_click(browser, + BROWSER_MOUSE_PRESS_1 | cocoa_mouse_flags_for_event(theEvent), + dragStart.x, + dragStart.y); } -- (void) rightMouseDown: (NSEvent *)theEvent +- (void)rightMouseDown:(NSEvent *)theEvent { - [self popUpContextMenuForEvent: theEvent]; + [self popUpContextMenuForEvent:theEvent]; } -- (void) mouseUp: (NSEvent *)theEvent +- (void)mouseUp:(NSEvent *)theEvent { - if (historyVisible) { - [self setHistoryVisible: NO]; - return; - } + if (historyVisible) { + [self setHistoryVisible:NO]; + return; + } - NSPoint location = [self convertMousePoint: theEvent]; + NSPoint location = [self convertMousePoint:theEvent]; - browser_mouse_state modifierFlags = cocoa_mouse_flags_for_event( theEvent ); + browser_mouse_state modifierFlags = cocoa_mouse_flags_for_event(theEvent); - if (isDragging) { - isDragging = NO; - browser_window_mouse_track( browser, (browser_mouse_state)0, location.x, location.y ); - } else { - modifierFlags |= BROWSER_MOUSE_CLICK_1; - if ([theEvent clickCount] == 2) modifierFlags |= BROWSER_MOUSE_DOUBLE_CLICK; - browser_window_mouse_click( browser, modifierFlags, location.x, location.y ); - } + if (isDragging) { + isDragging = NO; + browser_window_mouse_track(browser, (browser_mouse_state)0, location.x, location.y); + } else { + modifierFlags |= BROWSER_MOUSE_CLICK_1; + if ([theEvent clickCount] == 2) + modifierFlags |= BROWSER_MOUSE_DOUBLE_CLICK; + browser_window_mouse_click(browser, modifierFlags, location.x, location.y); + } } -#define squared(x) ((x)*(x)) +#define squared(x) ((x) * (x)) #define MinDragDistance (5.0) -- (void) mouseDragged: (NSEvent *)theEvent +- (void)mouseDragged:(NSEvent *)theEvent { - NSPoint location = [self convertMousePoint: theEvent]; - browser_mouse_state modifierFlags = cocoa_mouse_flags_for_event( theEvent ); + NSPoint location = [self convertMousePoint:theEvent]; + browser_mouse_state modifierFlags = cocoa_mouse_flags_for_event(theEvent); - if (!isDragging) { - const CGFloat distance = squared( dragStart.x - location.x ) + squared( dragStart.y - location.y ); + if (!isDragging) { + const CGFloat distance = squared(dragStart.x - location.x) + squared(dragStart.y - location.y); - if (distance >= squared( MinDragDistance)) { - isDragging = YES; - browser_window_mouse_click(browser, - BROWSER_MOUSE_DRAG_1 | modifierFlags, - dragStart.x, - dragStart.y); - } + if (distance >= squared(MinDragDistance)) { + isDragging = YES; + browser_window_mouse_click(browser, + BROWSER_MOUSE_DRAG_1 | modifierFlags, + dragStart.x, + dragStart.y); } + } - if (isDragging) { - browser_window_mouse_track(browser, - BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON | modifierFlags, - location.x, - location.y ); - } + if (isDragging) { + browser_window_mouse_track(browser, + BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON | modifierFlags, + location.x, + location.y); + } } -- (void) mouseMoved: (NSEvent *)theEvent +- (void)mouseMoved:(NSEvent *)theEvent { - if (historyVisible) return; + if (historyVisible) + return; - NSPoint location = [self convertMousePoint: theEvent]; + NSPoint location = [self convertMousePoint:theEvent]; - browser_window_mouse_track(browser, - cocoa_mouse_flags_for_event(theEvent), - location.x, - location.y); + browser_window_mouse_track(browser, + cocoa_mouse_flags_for_event(theEvent), + location.x, + location.y); } -- (void) mouseExited: (NSEvent *) theEvent +- (void)mouseExited:(NSEvent *)theEvent { - [[NSCursor arrowCursor] set]; + [[NSCursor arrowCursor] set]; } -- (void) keyDown: (NSEvent *)theEvent +- (void)keyDown:(NSEvent *)theEvent { - if (!historyVisible) { - [self interpretKeyEvents: [NSArray arrayWithObject: theEvent]]; - } else { - [history keyDown: theEvent]; - } + if (!historyVisible) { + [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + } else { + [history keyDown:theEvent]; + } } -- (void) insertText: (id)string +- (void)insertText:(id)string { - for (NSUInteger i = 0, length = [string length]; i < length; i++) { - unichar ch = [string characterAtIndex: i]; - if (!browser_window_key_press( browser, ch )) { - if (ch == ' ') [self scrollPageDown: self]; - break; - } + for (NSUInteger i = 0, length = [string length]; i < length; i++) { + unichar ch = [string characterAtIndex:i]; + if (!browser_window_key_press(browser, ch)) { + if (ch == ' ') + [self scrollPageDown:self]; + break; } - [self setMarkedText: nil]; + } + [self setMarkedText:nil]; } -- (void) moveLeft: (id)sender +- (void)moveLeft:(id)sender { - if (browser_window_key_press( browser, NS_KEY_LEFT )) return; - [self scrollHorizontal: -[[self enclosingScrollView] horizontalLineScroll]]; + if (browser_window_key_press(browser, NS_KEY_LEFT)) + return; + [self scrollHorizontal:-[[self enclosingScrollView] horizontalLineScroll]]; } -- (void) moveRight: (id)sender +- (void)moveRight:(id)sender { - if (browser_window_key_press( browser, NS_KEY_RIGHT )) return; - [self scrollHorizontal: [[self enclosingScrollView] horizontalLineScroll]]; + if (browser_window_key_press(browser, NS_KEY_RIGHT)) + return; + [self scrollHorizontal:[[self enclosingScrollView] horizontalLineScroll]]; } -- (void) moveUp: (id)sender +- (void)moveUp:(id)sender { - if (browser_window_key_press( browser, NS_KEY_UP )) return; - [self scrollVertical: -[[self enclosingScrollView] lineScroll]]; + if (browser_window_key_press(browser, NS_KEY_UP)) + return; + [self scrollVertical:-[[self enclosingScrollView] lineScroll]]; } -- (void) moveDown: (id)sender +- (void)moveDown:(id)sender { - if (browser_window_key_press( browser, NS_KEY_DOWN )) return; - [self scrollVertical: [[self enclosingScrollView] lineScroll]]; + if (browser_window_key_press(browser, NS_KEY_DOWN)) + return; + [self scrollVertical:[[self enclosingScrollView] lineScroll]]; } -- (void) deleteBackward: (id)sender +- (void)deleteBackward:(id)sender { - if (!browser_window_key_press( browser, NS_KEY_DELETE_LEFT )) { - [NSApp sendAction: @selector( goBack: ) to: nil from: self]; - } + if (!browser_window_key_press(browser, NS_KEY_DELETE_LEFT)) { + [NSApp sendAction:@selector(goBack:) to:nil from:self]; + } } -- (void) deleteForward: (id)sender +- (void)deleteForward:(id)sender { - browser_window_key_press( browser, NS_KEY_DELETE_RIGHT ); + browser_window_key_press(browser, NS_KEY_DELETE_RIGHT); } -- (void) cancelOperation: (id)sender +- (void)cancelOperation:(id)sender { - browser_window_key_press( browser, NS_KEY_ESCAPE ); + browser_window_key_press(browser, NS_KEY_ESCAPE); } -- (void) scrollPageUp: (id)sender +- (void)scrollPageUp:(id)sender { - if (browser_window_key_press( browser, NS_KEY_PAGE_UP )) { - return; - } - [self scrollVertical: -[self pageScroll]]; + if (browser_window_key_press(browser, NS_KEY_PAGE_UP)) { + return; + } + [self scrollVertical:-[self pageScroll]]; } -- (void) scrollPageDown: (id)sender +- (void)scrollPageDown:(id)sender { - if (browser_window_key_press( browser, NS_KEY_PAGE_DOWN )) { - return; - } - [self scrollVertical: [self pageScroll]]; + if (browser_window_key_press(browser, NS_KEY_PAGE_DOWN)) { + return; + } + [self scrollVertical:[self pageScroll]]; } -- (void) insertTab: (id)sender +- (void)insertTab:(id)sender { - browser_window_key_press( browser, NS_KEY_TAB ); + browser_window_key_press(browser, NS_KEY_TAB); } -- (void) insertBacktab: (id)sender +- (void)insertBacktab:(id)sender { - browser_window_key_press( browser, NS_KEY_SHIFT_TAB ); + browser_window_key_press(browser, NS_KEY_SHIFT_TAB); } -- (void) moveToBeginningOfLine: (id)sender +- (void)moveToBeginningOfLine:(id)sender { - browser_window_key_press( browser, NS_KEY_LINE_START ); + browser_window_key_press(browser, NS_KEY_LINE_START); } -- (void) moveToEndOfLine: (id)sender +- (void)moveToEndOfLine:(id)sender { - browser_window_key_press( browser, NS_KEY_LINE_END ); + browser_window_key_press(browser, NS_KEY_LINE_END); } -- (void) moveToBeginningOfDocument: (id)sender +- (void)moveToBeginningOfDocument:(id)sender { - if (browser_window_key_press( browser, NS_KEY_TEXT_START )) return; + if (browser_window_key_press(browser, NS_KEY_TEXT_START)) + return; } -- (void) scrollToBeginningOfDocument: (id) sender +- (void)scrollToBeginningOfDocument:(id)sender { - NSPoint origin = [self visibleRect].origin; - origin.y = 0; - [self scrollPoint: origin]; + NSPoint origin = [self visibleRect].origin; + origin.y = 0; + [self scrollPoint:origin]; } -- (void) moveToEndOfDocument: (id)sender +- (void)moveToEndOfDocument:(id)sender { - browser_window_key_press( browser, NS_KEY_TEXT_END ); + browser_window_key_press(browser, NS_KEY_TEXT_END); } -- (void) scrollToEndOfDocument: (id) sender +- (void)scrollToEndOfDocument:(id)sender { - NSPoint origin = [self visibleRect].origin; - origin.y = NSHeight( [self frame] ); - [self scrollPoint: origin]; + NSPoint origin = [self visibleRect].origin; + origin.y = NSHeight([self frame]); + [self scrollPoint:origin]; } -- (void) insertNewline: (id)sender +- (void)insertNewline:(id)sender { - browser_window_key_press( browser, NS_KEY_NL ); + browser_window_key_press(browser, NS_KEY_NL); } -- (void) selectAll: (id)sender +- (void)selectAll:(id)sender { - browser_window_key_press( browser, NS_KEY_SELECT_ALL ); + browser_window_key_press(browser, NS_KEY_SELECT_ALL); } -- (void) copy: (id)sender +- (void)copy:(id)sender { - browser_window_key_press( browser, NS_KEY_COPY_SELECTION ); + browser_window_key_press(browser, NS_KEY_COPY_SELECTION); } -- (void) cut: (id)sender +- (void)cut:(id)sender { - browser_window_key_press( browser, NS_KEY_CUT_SELECTION ); + browser_window_key_press(browser, NS_KEY_CUT_SELECTION); } -- (void) paste: (id)sender +- (void)paste:(id)sender { - browser_window_key_press( browser, NS_KEY_PASTE ); + browser_window_key_press(browser, NS_KEY_PASTE); } -- (BOOL) acceptsFirstResponder +- (BOOL)acceptsFirstResponder { - return YES; + return YES; } -- (void) adjustFrame +- (void)adjustFrame { - browser_window_schedule_reformat(browser); + browser_window_schedule_reformat(browser); - [super adjustFrame]; + [super adjustFrame]; } -- (BOOL) isHistoryVisible +- (BOOL)isHistoryVisible { - return historyVisible; + return historyVisible; } -- (void) setHistoryVisible: (BOOL)newVisible +- (void)setHistoryVisible:(BOOL)newVisible { - if (newVisible == historyVisible) return; - historyVisible = newVisible; + if (newVisible == historyVisible) + return; + historyVisible = newVisible; - if (historyVisible) { - if (nil == history) { - history = [[LocalHistoryController alloc] initWithBrowser: self]; - } - [history attachToView: [(BrowserWindowController *)[[self window] windowController] historyButton]]; - } else { - [history detach]; + if (historyVisible) { + if (nil == history) { + history = [[LocalHistoryController alloc] initWithBrowser:self]; } + [history attachToView:[(BrowserWindowController *)[[self window] windowController] historyButton]]; + } else { + [history detach]; + } } -- (void) scrollHorizontal: (CGFloat) amount +- (void)scrollHorizontal:(CGFloat)amount { - NSPoint currentPoint = [self visibleRect].origin; - currentPoint.x += amount; - [self scrollPoint: currentPoint]; + NSPoint currentPoint = [self visibleRect].origin; + currentPoint.x += amount; + [self scrollPoint:currentPoint]; } -- (void) scrollVertical: (CGFloat) amount +- (void)scrollVertical:(CGFloat)amount { - NSPoint currentPoint = [self visibleRect].origin; - currentPoint.y += amount; - [self scrollPoint: currentPoint]; + NSPoint currentPoint = [self visibleRect].origin; + currentPoint.y += amount; + [self scrollPoint:currentPoint]; } -- (CGFloat) pageScroll +- (CGFloat)pageScroll { - return NSHeight( [[self superview] frame] ) - [[self enclosingScrollView] pageScroll]; + return NSHeight([[self superview] frame]) - [[self enclosingScrollView] pageScroll]; } - -- (void) popUpContextMenuForEvent: (NSEvent *) event +- (void)popUpContextMenuForEvent:(NSEvent *)event { - NSMenu *popupMenu = [[NSMenu alloc] initWithTitle: @""]; - NSPoint point = [self convertMousePoint: event]; + NSMenu *popupMenu = [[NSMenu alloc] initWithTitle:@""]; + NSPoint point = [self convertMousePoint:event]; - struct browser_window_features cont; + struct browser_window_features cont; - browser_window_get_features(browser, point.x, point.y, &cont); + browser_window_get_features(browser, point.x, point.y, &cont); - if (cont.object != NULL) { - NSString *imageURL = [NSString stringWithUTF8String: nsurl_access(hlcache_handle_get_url( cont.object ))]; + if (cont.object != NULL) { + NSString *imageURL = [NSString stringWithUTF8String:nsurl_access(hlcache_handle_get_url(cont.object))]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Open image in new tab", @"Context menu" ) - action: @selector(cmOpenURLInTab:) - keyEquivalent: @""] setRepresentedObject: imageURL]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Open image in new window", @"Context menu" ) - action: @selector(cmOpenURLInWindow:) - keyEquivalent: @""] setRepresentedObject: imageURL]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Save image as", @"Context menu" ) - action: @selector(cmDownloadURL:) - keyEquivalent: @""] setRepresentedObject: imageURL]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Copy image", @"Context menu" ) - action: @selector(cmImageCopy:) - keyEquivalent: @""] setRepresentedObject: (__bridge id)content_get_bitmap( cont.object )]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Open image in new tab", @"Context menu") + action:@selector(cmOpenURLInTab:) + keyEquivalent:@""] setRepresentedObject:imageURL]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Open image in new window", @"Context menu") + action:@selector(cmOpenURLInWindow:) + keyEquivalent:@""] setRepresentedObject:imageURL]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Save image as", @"Context menu") + action:@selector(cmDownloadURL:) + keyEquivalent:@""] setRepresentedObject:imageURL]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Copy image", @"Context menu") + action:@selector(cmImageCopy:) + keyEquivalent:@""] setRepresentedObject:(__bridge id)content_get_bitmap(cont.object)]; - [popupMenu addItem: [NSMenuItem separatorItem]]; - } + [popupMenu addItem:[NSMenuItem separatorItem]]; + } - if (cont.link != NULL) { - NSString *target = [NSString stringWithUTF8String: nsurl_access(cont.link)]; - - [[popupMenu addItemWithTitle: NSLocalizedString( @"Open link in new tab", @"Context menu" ) - action: @selector(cmOpenURLInTab:) - keyEquivalent: @""] setRepresentedObject: target]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Open link in new window", @"Context menu" ) - action: @selector(cmOpenURLInWindow:) - keyEquivalent: @""] setRepresentedObject: target]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Save link target", @"Context menu" ) - action: @selector(cmDownloadURL:) - keyEquivalent: @""] setRepresentedObject: target]; - [[popupMenu addItemWithTitle: NSLocalizedString( @"Copy link", @"Context menu" ) - action: @selector(cmLinkCopy:) - keyEquivalent: @""] setRepresentedObject: target]; - - [popupMenu addItem: [NSMenuItem separatorItem]]; - } + if (cont.link != NULL) { + NSString *target = [NSString stringWithUTF8String:nsurl_access(cont.link)]; + + [[popupMenu addItemWithTitle:NSLocalizedString(@"Open link in new tab", @"Context menu") + action:@selector(cmOpenURLInTab:) + keyEquivalent:@""] setRepresentedObject:target]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Open link in new window", @"Context menu") + action:@selector(cmOpenURLInWindow:) + keyEquivalent:@""] setRepresentedObject:target]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Save link target", @"Context menu") + action:@selector(cmDownloadURL:) + keyEquivalent:@""] setRepresentedObject:target]; + [[popupMenu addItemWithTitle:NSLocalizedString(@"Copy link", @"Context menu") + action:@selector(cmLinkCopy:) + keyEquivalent:@""] setRepresentedObject:target]; + + [popupMenu addItem:[NSMenuItem separatorItem]]; + } - [popupMenu addItemWithTitle: NSLocalizedString( @"Back", @"Context menu" ) - action: @selector(goBack:) keyEquivalent: @""]; - [popupMenu addItemWithTitle: NSLocalizedString( @"Reload", @"Context menu" ) - action: @selector(reloadPage:) keyEquivalent: @""]; - [popupMenu addItemWithTitle: NSLocalizedString( @"Forward", @"Context menu" ) - action: @selector(goForward:) keyEquivalent: @""]; - [popupMenu addItemWithTitle: NSLocalizedString( @"View Source", @"Context menu" ) - action: @selector(viewSource:) keyEquivalent: @""]; - - [NSMenu popUpContextMenu: popupMenu withEvent: event forView: self]; -} - -- (IBAction) cmOpenURLInTab: (id)sender -{ - nsurl *url; - nserror error; - - error = nsurl_create([[sender representedObject] UTF8String], &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY | - BW_CREATE_TAB | - BW_CREATE_CLONE, - url, - NULL, - browser, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + [popupMenu addItemWithTitle:NSLocalizedString(@"Back", @"Context menu") + action:@selector(goBack:) + keyEquivalent:@""]; + [popupMenu addItemWithTitle:NSLocalizedString(@"Reload", @"Context menu") + action:@selector(reloadPage:) + keyEquivalent:@""]; + [popupMenu addItemWithTitle:NSLocalizedString(@"Forward", @"Context menu") + action:@selector(goForward:) + keyEquivalent:@""]; + [popupMenu addItemWithTitle:NSLocalizedString(@"View Source", @"Context menu") + action:@selector(viewSource:) + keyEquivalent:@""]; + + [NSMenu popUpContextMenu:popupMenu withEvent:event forView:self]; +} + +- (IBAction)cmOpenURLInTab:(id)sender +{ + nsurl *url; + nserror error; + + error = nsurl_create([[sender representedObject] UTF8String], &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY | BW_CREATE_TAB | BW_CREATE_CLONE, + url, + NULL, + browser, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (IBAction) cmOpenURLInWindow: (id)sender +- (IBAction)cmOpenURLInWindow:(id)sender { - nsurl *url; - nserror error; + nsurl *url; + nserror error; - error = nsurl_create([[sender representedObject] UTF8String], &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY | - BW_CREATE_CLONE, - url, - NULL, - browser, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + error = nsurl_create([[sender representedObject] UTF8String], &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY | BW_CREATE_CLONE, + url, + NULL, + browser, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (IBAction) cmDownloadURL: (id)sender +- (IBAction)cmDownloadURL:(id)sender { - nsurl *url; + nsurl *url; - if (nsurl_create([[sender representedObject] UTF8String], &url) == NSERROR_OK) { - browser_window_navigate(browser, - url, - NULL, - BW_NAVIGATE_DOWNLOAD, - NULL, - NULL, - NULL); - nsurl_unref(url); - } + if (nsurl_create([[sender representedObject] UTF8String], &url) == NSERROR_OK) { + browser_window_navigate(browser, + url, + NULL, + BW_NAVIGATE_DOWNLOAD, + NULL, + NULL, + NULL); + nsurl_unref(url); + } } -- (IBAction) cmImageCopy: (id)sender +- (IBAction)cmImageCopy:(id)sender { - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - [pb declareTypes: [NSArray arrayWithObject: NSTIFFPboardType] owner: nil]; - [pb setData: [[sender representedObject] TIFFRepresentation] forType: NSTIFFPboardType]; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; + [pb setData:[[sender representedObject] TIFFRepresentation] forType:NSTIFFPboardType]; } -- (IBAction) cmLinkCopy: (id)sender +- (IBAction)cmLinkCopy:(id)sender { - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - [pb declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil]; - [pb setString: [sender representedObject] forType: NSStringPboardType]; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; + [pb setString:[sender representedObject] forType:NSStringPboardType]; } - // MARK: - // MARK: Accepting dragged URLs -- (NSDragOperation)draggingEntered:(id )sender +- (NSDragOperation)draggingEntered:(id)sender { - if ((NSDragOperationCopy | NSDragOperationGeneric) & [sender draggingSourceOperationMask]) { - return NSDragOperationCopy; - } + if ((NSDragOperationCopy | NSDragOperationGeneric) & [sender draggingSourceOperationMask]) { + return NSDragOperationCopy; + } - return NSDragOperationNone; + return NSDragOperationNone; } -- (BOOL)prepareForDragOperation:(id )sender +- (BOOL)prepareForDragOperation:(id)sender { - return YES; + return YES; } -- (BOOL)performDragOperation:(id )sender +- (BOOL)performDragOperation:(id)sender { - nsurl *url; - nserror error; + nsurl *url; + nserror error; - NSPasteboard *pb = [sender draggingPasteboard]; + NSPasteboard *pb = [sender draggingPasteboard]; - NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObjects: @"public.url", NSURLPboardType, nil]]; + NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObjects:@"public.url", NSURLPboardType, nil]]; - NSString *urlstr = nil; + NSString *urlstr = nil; - if ([type isEqualToString: NSURLPboardType]) { - urlstr = [[NSURL URLFromPasteboard: pb] absoluteString]; - } else { - urlstr = [pb stringForType: type]; - } + if ([type isEqualToString:NSURLPboardType]) { + urlstr = [[NSURL URLFromPasteboard:pb] absoluteString]; + } else { + urlstr = [pb stringForType:type]; + } - error = nsurl_create([urlstr UTF8String], &url); - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } else { - browser_window_navigate(browser, - url, - NULL, - BW_NAVIGATE_DOWNLOAD, - NULL, - NULL, - NULL); - nsurl_unref(url); - } + error = nsurl_create([urlstr UTF8String], &url); + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(browser, + url, + NULL, + BW_NAVIGATE_DOWNLOAD, + NULL, + NULL, + NULL); + nsurl_unref(url); + } - return YES; + return YES; } // MARK: - // MARK: NSTextInput protocol implementation -- (void) setMarkedText: (id) aString selectedRange: (NSRange) selRange +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange { - markedText = [aString isEqualToString: @""] ? nil : [aString copy]; + markedText = [aString isEqualToString:@""] ? nil : [aString copy]; } -- (void) unmarkText +- (void)unmarkText { - [self setMarkedText: nil]; + [self setMarkedText:nil]; } -- (BOOL) hasMarkedText +- (BOOL)hasMarkedText { - return markedText != nil; + return markedText != nil; } -- (NSInteger) conversationIdentifier +- (NSInteger)conversationIdentifier { - return (NSInteger)self; + return (NSInteger)self; } -- (NSAttributedString *) attributedSubstringFromRange: (NSRange) theRange +- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange { - return [[NSAttributedString alloc] initWithString: @""]; + return [[NSAttributedString alloc] initWithString:@""]; } -- (NSRange) markedRange +- (NSRange)markedRange { - return NSMakeRange( NSNotFound, 0 ); + return NSMakeRange(NSNotFound, 0); } -- (NSRange) selectedRange +- (NSRange)selectedRange { - return NSMakeRange( NSNotFound, 0 ); + return NSMakeRange(NSNotFound, 0); } -- (NSRect) firstRectForCharacterRange: (NSRange) theRange +- (NSRect)firstRectForCharacterRange:(NSRange)theRange { - return NSZeroRect; + return NSZeroRect; } -- (NSUInteger) characterIndexForPoint: (NSPoint) thePoint +- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { - return 0; + return 0; } -- (NSArray *) validAttributesForMarkedText +- (NSArray *)validAttributesForMarkedText { - return [NSArray array]; + return [NSArray array]; } -- (void) doCommandBySelector: (SEL) sel +- (void)doCommandBySelector:(SEL)sel { - [super doCommandBySelector: sel]; + [super doCommandBySelector:sel]; } @end diff --git a/frontends/cocoa/BrowserViewController.m b/frontends/cocoa/BrowserViewController.m index 4db479a1b..9848654f8 100644 --- a/frontends/cocoa/BrowserViewController.m +++ b/frontends/cocoa/BrowserViewController.m @@ -32,8 +32,6 @@ #import "cocoa/BrowserWindowController.h" #import "cocoa/fetch.h" - - @implementation BrowserViewController @synthesize browser; @@ -47,328 +45,313 @@ @synthesize canGoBack; @synthesize canGoForward; - -- (instancetype)initWithBrowser: (struct browser_window *) bw +- (instancetype)initWithBrowser:(struct browser_window *)bw { - if ((self = [super initWithNibName: @"Browser" bundle: nil]) == nil) { - return nil; - } + if ((self = [super initWithNibName:@"Browser" bundle:nil]) == nil) { + return nil; + } - browser = bw; + browser = bw; - return self; + return self; } - -- (IBAction) navigate: (id) sender +- (IBAction)navigate:(id)sender { - nsurl *urlns; - nserror error; - - error = nsurl_create([url UTF8String], &urlns); - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } else { - browser_window_navigate(browser, - urlns, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - nsurl_unref(urlns); - } + nsurl *urlns; + nserror error; + + error = nsurl_create([url UTF8String], &urlns); + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } else { + browser_window_navigate(browser, + urlns, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(urlns); + } } - -- (void) awakeFromNib +- (void)awakeFromNib { - [browserView setBrowser: browser]; + [browserView setBrowser:browser]; } - -- (IBAction) zoomIn: (id) sender +- (IBAction)zoomIn:(id)sender { - browser_window_set_scale(browser, - browser_window_get_scale(browser) * 1.1, - true); + browser_window_set_scale(browser, + browser_window_get_scale(browser) * 1.1, + true); } - -- (IBAction) zoomOut: (id) sender +- (IBAction)zoomOut:(id)sender { - browser_window_set_scale(browser, - browser_window_get_scale(browser) * 0.9, - true); + browser_window_set_scale(browser, + browser_window_get_scale(browser) * 0.9, + true); } - -- (IBAction) zoomOriginal: (id) sender +- (IBAction)zoomOriginal:(id)sender { - browser_window_set_scale(browser, - (float)nsoption_int(scale) / 100.0, - true); + browser_window_set_scale(browser, + (float)nsoption_int(scale) / 100.0, + true); } - -- (IBAction) backForwardSelected: (id) sender +- (IBAction)backForwardSelected:(id)sender { - if ([sender selectedSegment] == 0) { - [self goBack: sender]; - } else { - [self goForward: sender]; - } + if ([sender selectedSegment] == 0) { + [self goBack:sender]; + } else { + [self goForward:sender]; + } } - -- (IBAction) goBack: (id) sender +- (IBAction)goBack:(id)sender { - if (browser && browser_window_history_back_available( browser )) { - browser_window_history_back(browser, false); - [self updateBackForward]; - } + if (browser && browser_window_history_back_available(browser)) { + browser_window_history_back(browser, false); + [self updateBackForward]; + } } - -- (IBAction) goForward: (id) sender +- (IBAction)goForward:(id)sender { - if (browser && browser_window_history_forward_available( browser )) { - browser_window_history_forward(browser, false); - [self updateBackForward]; - } + if (browser && browser_window_history_forward_available(browser)) { + browser_window_history_forward(browser, false); + [self updateBackForward]; + } } - -- (IBAction) goHome: (id) sender +- (IBAction)goHome:(id)sender { - nsurl *urlns; - nserror error; - - error = nsurl_create(nsoption_charp(homepage_url), &urlns); - if (error == NSERROR_OK) { - error = browser_window_navigate(browser, - urlns, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - nsurl_unref(urlns); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + nsurl *urlns; + nserror error; + + error = nsurl_create(nsoption_charp(homepage_url), &urlns); + if (error == NSERROR_OK) { + error = browser_window_navigate(browser, + urlns, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(urlns); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } - -- (IBAction) reloadPage: (id) sender +- (IBAction)reloadPage:(id)sender { - browser_window_reload( browser, true ); + browser_window_reload(browser, true); } - -- (IBAction) stopLoading: (id) sender +- (IBAction)stopLoading:(id)sender { - browser_window_stop( browser ); + browser_window_stop(browser); } - -- (IBAction) viewSource: (id) sender +- (IBAction)viewSource:(id)sender { - struct hlcache_handle *content; - size_t size; - const char *source; - char *path = NULL; - - if (browser == NULL) { - return; - } - content = browser_window_get_content(browser); - if (content == NULL) { - return; - } - source = content_get_source_data(content, &size); - if (source == NULL) { - return; - } - - /* try to load local files directly. */ - netsurf_nsurl_to_path(hlcache_handle_get_url(content), &path); - - if (path == NULL) { - /* We cannot release the requested filename until after it + struct hlcache_handle *content; + size_t size; + const char *source; + char *path = NULL; + + if (browser == NULL) { + return; + } + content = browser_window_get_content(browser); + if (content == NULL) { + return; + } + source = content_get_source_data(content, &size); + if (source == NULL) { + return; + } + + /* try to load local files directly. */ + netsurf_nsurl_to_path(hlcache_handle_get_url(content), &path); + + if (path == NULL) { + /* We cannot release the requested filename until after it * has finished being used. As we can't easily find out when * this is, we simply don't bother releasing it and simply * allow it to be re-used next time NetSurf is started. The * memory overhead from doing this is under 1 byte per * filename. */ - const char *filename = filename_request(); - const char *extension = "txt"; - fprintf(stderr, "filename '%p'\n", filename); - if (filename == NULL) - return; - lwc_string *str = content_get_mime_type(content); - if (str) { - NSString *mime = [NSString stringWithUTF8String:lwc_string_data(str)]; - NSString *uti = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mime, NULL); - NSString *ext = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassFilenameExtension); - extension = [ext UTF8String]; - lwc_string_unref(str); - } - - NSURL *dataUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%s.%s", filename, extension] - relativeToURL:[NSURL fileURLWithPath:@TEMP_FILENAME_PREFIX]]; - - - NSData *data = [NSData dataWithBytes:source length:size]; - [data writeToURL:dataUrl atomically:NO]; - path = (char *)[[dataUrl path] UTF8String]; + const char *filename = filename_request(); + const char *extension = "txt"; + fprintf(stderr, "filename '%p'\n", filename); + if (filename == NULL) + return; + lwc_string *str = content_get_mime_type(content); + if (str) { + NSString *mime = [NSString stringWithUTF8String:lwc_string_data(str)]; + NSString *uti = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mime, NULL); + NSString *ext = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassFilenameExtension); + extension = [ext UTF8String]; + lwc_string_unref(str); } - if (path) { - NSString * p = [NSString stringWithUTF8String: path]; - NSWorkspace * ws = [NSWorkspace sharedWorkspace]; - [ws openFile:p withApplication:@"Xcode"]; - } -} + NSURL *dataUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%s.%s", filename, extension] + relativeToURL:[NSURL fileURLWithPath:@TEMP_FILENAME_PREFIX]]; + + NSData *data = [NSData dataWithBytes:source length:size]; + [data writeToURL:dataUrl atomically:NO]; + path = (char *)[[dataUrl path] UTF8String]; + } + if (path) { + NSString *p = [NSString stringWithUTF8String:path]; + NSWorkspace *ws = [NSWorkspace sharedWorkspace]; + [ws openFile:p withApplication:@"Xcode"]; + } +} static inline bool -compare_float( float a, float b ) +compare_float(float a, float b) { - const float epsilon = 0.00001; + const float epsilon = 0.00001; - if (a == b) { - return true; - } + if (a == b) { + return true; + } - return fabs( (a - b) / b ) <= epsilon; + return fabs((a - b) / b) <= epsilon; } -- (BOOL) validateUserInterfaceItem: (id) item +- (BOOL)validateUserInterfaceItem:(id)item { - SEL action = [item action]; + SEL action = [item action]; - if (action == @selector(copy:)) { - return browser_window_get_editor_flags( browser ) & BW_EDITOR_CAN_COPY; - } + if (action == @selector(copy:)) { + return browser_window_get_editor_flags(browser) & BW_EDITOR_CAN_COPY; + } - if (action == @selector(cut:)) { - return browser_window_get_editor_flags( browser ) & BW_EDITOR_CAN_CUT; - } + if (action == @selector(cut:)) { + return browser_window_get_editor_flags(browser) & BW_EDITOR_CAN_CUT; + } - if (action == @selector(paste:)) { - return browser_window_get_editor_flags( browser ) & BW_EDITOR_CAN_PASTE; - } + if (action == @selector(paste:)) { + return browser_window_get_editor_flags(browser) & BW_EDITOR_CAN_PASTE; + } - if (action == @selector( stopLoading: )) { - return browser_window_stop_available( browser ); - } + if (action == @selector(stopLoading:)) { + return browser_window_stop_available(browser); + } - if (action == @selector( zoomOriginal: )) { - return !compare_float( browser_window_get_scale(browser), (float)nsoption_int(scale) / 100.0 ); - } + if (action == @selector(zoomOriginal:)) { + return !compare_float(browser_window_get_scale(browser), (float)nsoption_int(scale) / 100.0); + } - if (action == @selector( goBack: )) { - return canGoBack; - } + if (action == @selector(goBack:)) { + return canGoBack; + } - if (action == @selector( goForward: )) { - return canGoForward; - } + if (action == @selector(goForward:)) { + return canGoForward; + } - return YES; + return YES; } - -- (void) updateBackForward +- (void)updateBackForward { - [browserView updateHistory]; - [self setCanGoBack: browser != NULL && browser_window_history_back_available( browser )]; - [self setCanGoForward: browser != NULL && browser_window_history_forward_available( browser )]; + [browserView updateHistory]; + [self setCanGoBack:browser != NULL && browser_window_history_back_available(browser)]; + [self setCanGoForward:browser != NULL && browser_window_history_forward_available(browser)]; } -- (void) contentUpdated +- (void)contentUpdated { - [browserView updateHistory]; + [browserView updateHistory]; } struct history_add_menu_item_data { - NSInteger index; - void *menu; - void *target; + NSInteger index; + void *menu; + void *target; }; - -static NSMenu *get_menu(const struct history_add_menu_item_data *data) { +static NSMenu *get_menu(const struct history_add_menu_item_data *data) +{ return (__bridge NSMenu *)data->menu; } -static id get_target (const struct history_add_menu_item_data *data) { +static id get_target(const struct history_add_menu_item_data *data) +{ return (__bridge id)data->target; } static bool history_add_menu_item_cb(const struct browser_window *bw, - int x0, int y0, int x1, int y1, - const struct history_entry *page, - void *user_data ) + int x0, int y0, int x1, int y1, + const struct history_entry *page, + void *user_data) { - struct history_add_menu_item_data *data = user_data; - - NSMenuItem *item = nil; - if (data->index < [get_menu(data) numberOfItems]) { - item = [get_menu(data) itemAtIndex: data->index]; - } else { - item = [[NSMenuItem alloc] initWithTitle: @"" - action: @selector( historyItemSelected: ) - keyEquivalent: @""]; - [get_menu(data) addItem: item]; - } - ++data->index; - - [item setTarget: get_target(data)]; - [item setTitle: [NSString stringWithUTF8String: browser_window_history_entry_get_title( page )]]; - [item setRepresentedObject: [NSValue valueWithPointer: page]]; - - return true; + struct history_add_menu_item_data *data = user_data; + + NSMenuItem *item = nil; + if (data->index < [get_menu(data) numberOfItems]) { + item = [get_menu(data) itemAtIndex:data->index]; + } else { + item = [[NSMenuItem alloc] initWithTitle:@"" + action:@selector(historyItemSelected:) + keyEquivalent:@""]; + [get_menu(data) addItem:item]; + } + ++data->index; + + [item setTarget:get_target(data)]; + [item setTitle:[NSString stringWithUTF8String:browser_window_history_entry_get_title(page)]]; + [item setRepresentedObject:[NSValue valueWithPointer:page]]; + + return true; } -- (IBAction) historyItemSelected: (id) sender +- (IBAction)historyItemSelected:(id)sender { - struct history_entry *entry = [[sender representedObject] pointerValue]; - browser_window_history_go( browser, entry, false ); - [self updateBackForward]; + struct history_entry *entry = [[sender representedObject] pointerValue]; + browser_window_history_go(browser, entry, false); + [self updateBackForward]; } -- (void) buildBackMenu: (NSMenu *)menu +- (void)buildBackMenu:(NSMenu *)menu { - struct history_add_menu_item_data data = { - .index = 0, - .menu = (__bridge void *)menu, - .target = (__bridge void *)self - }; - browser_window_history_enumerate_back(browser, - history_add_menu_item_cb, - &data); - while (data.index < [menu numberOfItems]) { - [menu removeItemAtIndex: data.index]; - } + struct history_add_menu_item_data data = { + .index = 0, + .menu = (__bridge void *)menu, + .target = (__bridge void *)self + }; + browser_window_history_enumerate_back(browser, + history_add_menu_item_cb, + &data); + while (data.index < [menu numberOfItems]) { + [menu removeItemAtIndex:data.index]; + } } -- (void) buildForwardMenu: (NSMenu *)menu +- (void)buildForwardMenu:(NSMenu *)menu { - struct history_add_menu_item_data data = { - .index = 0, - .menu = (__bridge void *)menu, - .target = (__bridge void *)self - }; - browser_window_history_enumerate_forward(browser, - history_add_menu_item_cb, - &data); - while (data.index < [menu numberOfItems]) { - [menu removeItemAtIndex: data.index]; - } + struct history_add_menu_item_data data = { + .index = 0, + .menu = (__bridge void *)menu, + .target = (__bridge void *)self + }; + browser_window_history_enumerate_forward(browser, + history_add_menu_item_cb, + &data); + while (data.index < [menu numberOfItems]) { + [menu removeItemAtIndex:data.index]; + } } @end diff --git a/frontends/cocoa/BrowserWindow.m b/frontends/cocoa/BrowserWindow.m index f01b17a25..f30dc17a7 100644 --- a/frontends/cocoa/BrowserWindow.m +++ b/frontends/cocoa/BrowserWindow.m @@ -21,9 +21,9 @@ @implementation BrowserWindow -- (void) performClose: (id) sender +- (void)performClose:(id)sender { - [[self windowController] closeCurrentTab: sender]; + [[self windowController] closeCurrentTab:sender]; } @end diff --git a/frontends/cocoa/BrowserWindowController.m b/frontends/cocoa/BrowserWindowController.m index 1fa78b47b..ac3cf18e6 100644 --- a/frontends/cocoa/BrowserWindowController.m +++ b/frontends/cocoa/BrowserWindowController.m @@ -31,14 +31,12 @@ #import "cocoa/gui.h" #import "cocoa/NetsurfApp.h" - @interface BrowserWindowController () -- (void) canCloseAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo; +- (void)canCloseAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo; @end - @implementation BrowserWindowController @synthesize tabBar; @@ -52,206 +50,211 @@ @synthesize activeBrowser; @synthesize activeBrowserController; -- (id) init +- (id)init { - if (nil == (self = [super initWithWindowNibName: @"BrowserWindow"])) return nil; - - return self; -} + if (nil == (self = [super initWithWindowNibName:@"BrowserWindow"])) + return nil; + return self; +} -- (void) awakeFromNib +- (void)awakeFromNib { - [tabBar setShowAddTabButton: YES]; - [tabBar setTearOffStyle: PSMTabBarTearOffMiniwindow]; - [tabBar setCanCloseOnlyTab: YES]; - [tabBar setHideForSingleTab: YES]; - - NSButton *b = [tabBar addTabButton]; - [b setTarget: self]; - [b setAction: @selector(newTab:)]; - - [urlField setRefreshAction: @selector(reloadPage:)]; - [urlField bind: @"favicon" toObject: activeBrowserController withKeyPath: @"selection.favicon" options: nil]; - - [self bind: @"canGoBack" - toObject: activeBrowserController withKeyPath: @"selection.canGoBack" - options: nil]; - [self bind: @"canGoForward" - toObject: activeBrowserController withKeyPath: @"selection.canGoForward" - options: nil]; - - [navigationControl setMenu: historyBackMenu forSegment: 0]; - [navigationControl setMenu: historyForwardMenu forSegment: 1]; + [tabBar setShowAddTabButton:YES]; + [tabBar setTearOffStyle:PSMTabBarTearOffMiniwindow]; + [tabBar setCanCloseOnlyTab:YES]; + [tabBar setHideForSingleTab:YES]; + + NSButton *b = [tabBar addTabButton]; + [b setTarget:self]; + [b setAction:@selector(newTab:)]; + + [urlField setRefreshAction:@selector(reloadPage:)]; + [urlField bind:@"favicon" toObject:activeBrowserController withKeyPath:@"selection.favicon" options:nil]; + + [self bind:@"canGoBack" + toObject:activeBrowserController + withKeyPath:@"selection.canGoBack" + options:nil]; + [self bind:@"canGoForward" + toObject:activeBrowserController + withKeyPath:@"selection.canGoForward" + options:nil]; + + [navigationControl setMenu:historyBackMenu forSegment:0]; + [navigationControl setMenu:historyForwardMenu forSegment:1]; } -- (void) addTab: (BrowserViewController *)browser +- (void)addTab:(BrowserViewController *)browser { - NSTabViewItem *item = [[NSTabViewItem alloc] initWithIdentifier: browser]; - - [item setView: [browser view]]; - [item bind: @"label" toObject: browser withKeyPath: @"title" options: nil]; - - [tabView addTabViewItem: item]; - [browser setWindowController: self]; - - [tabView selectTabViewItem: item]; + NSTabViewItem *item = [[NSTabViewItem alloc] initWithIdentifier:browser]; + + [item setView:[browser view]]; + [item bind:@"label" toObject:browser withKeyPath:@"title" options:nil]; + + [tabView addTabViewItem:item]; + [browser setWindowController:self]; + + [tabView selectTabViewItem:item]; } -- (void) removeTab: (BrowserViewController *)browser +- (void)removeTab:(BrowserViewController *)browser { - NSUInteger itemIndex = [tabView indexOfTabViewItemWithIdentifier: browser]; - if (itemIndex != NSNotFound) { - NSTabViewItem *item = [tabView tabViewItemAtIndex: itemIndex]; - [tabView removeTabViewItem: item]; - [browser setWindowController: nil]; - } + NSUInteger itemIndex = [tabView indexOfTabViewItemWithIdentifier:browser]; + if (itemIndex != NSNotFound) { + NSTabViewItem *item = [tabView tabViewItemAtIndex:itemIndex]; + [tabView removeTabViewItem:item]; + [browser setWindowController:nil]; + } } -- (BOOL) windowShouldClose: (NSWindow *) window +- (BOOL)windowShouldClose:(NSWindow *)window { - if ([tabView numberOfTabViewItems] <= 1) return YES; - if ([[NSUserDefaults standardUserDefaults] boolForKey: kAlwaysCloseMultipleTabs]) return YES; - - NSAlert *ask = [NSAlert alertWithMessageText: NSLocalizedString( @"Do you really want to close this window?", nil ) - defaultButton: NSLocalizedString( @"Yes", @"'Yes' button" ) - alternateButton: NSLocalizedString( @"No" , @"'No' button" ) - otherButton:nil - informativeTextWithFormat: NSLocalizedString( @"There are %d tabs open, do you want to close them all?", nil ), - [tabView numberOfTabViewItems]]; - [ask setShowsSuppressionButton:YES]; - - [ask beginSheetModalForWindow: window modalDelegate:self didEndSelector:@selector(canCloseAlertDidEnd:returnCode:contextInfo:) - contextInfo: NULL]; - - return NO; + if ([tabView numberOfTabViewItems] <= 1) + return YES; + if ([[NSUserDefaults standardUserDefaults] boolForKey:kAlwaysCloseMultipleTabs]) + return YES; + + NSAlert *ask = [NSAlert alertWithMessageText:NSLocalizedString(@"Do you really want to close this window?", nil) + defaultButton:NSLocalizedString(@"Yes", @"'Yes' button") + alternateButton:NSLocalizedString(@"No", @"'No' button") + otherButton:nil + informativeTextWithFormat:NSLocalizedString(@"There are %d tabs open, do you want to close them all?", nil), + [tabView numberOfTabViewItems]]; + [ask setShowsSuppressionButton:YES]; + + [ask beginSheetModalForWindow:window + modalDelegate:self + didEndSelector:@selector(canCloseAlertDidEnd:returnCode:contextInfo:) + contextInfo:NULL]; + + return NO; } -- (void) canCloseAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo +- (void)canCloseAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo { - if (returnCode == NSModalResponseOK) { - [[NSUserDefaults standardUserDefaults] setBool: [[alert suppressionButton] state] == NSOnState - forKey: kAlwaysCloseMultipleTabs]; - [[self window] close]; - } + if (returnCode == NSModalResponseOK) { + [[NSUserDefaults standardUserDefaults] setBool:[[alert suppressionButton] state] == NSOnState + forKey:kAlwaysCloseMultipleTabs]; + [[self window] close]; + } } -- (void) windowWillClose: (NSNotification *)notification +- (void)windowWillClose:(NSNotification *)notification { - for (NSTabViewItem *tab in [tabView tabViewItems]) { - [tabView removeTabViewItem: tab]; - } + for (NSTabViewItem *tab in [tabView tabViewItems]) { + [tabView removeTabViewItem:tab]; + } } -- (IBAction) newTab: (id) sender +- (IBAction)newTab:(id)sender { - nsurl *url; - nserror error; - - if (nsoption_charp(homepage_url) != NULL) { - error = nsurl_create(nsoption_charp(homepage_url), &url); - } else { - error = nsurl_create(NETSURF_HOMEPAGE, &url); - } - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY | - BW_CREATE_TAB, - url, - NULL, - [activeBrowser browser], - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + nsurl *url; + nserror error; + + if (nsoption_charp(homepage_url) != NULL) { + error = nsurl_create(nsoption_charp(homepage_url), &url); + } else { + error = nsurl_create(NETSURF_HOMEPAGE, &url); + } + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY | BW_CREATE_TAB, + url, + NULL, + [activeBrowser browser], + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (IBAction) closeCurrentTab: (id) sender +- (IBAction)closeCurrentTab:(id)sender { - [self removeTab: activeBrowser]; + [self removeTab:activeBrowser]; } -- (void) setActiveBrowser: (BrowserViewController *)newBrowser +- (void)setActiveBrowser:(BrowserViewController *)newBrowser { - activeBrowser = newBrowser; - //[self setNextResponder: activeBrowser]; + activeBrowser = newBrowser; + //[self setNextResponder: activeBrowser]; } -- (void) setCanGoBack: (BOOL)can +- (void)setCanGoBack:(BOOL)can { - [navigationControl setEnabled: can forSegment: 0]; + [navigationControl setEnabled:can forSegment:0]; } -- (BOOL) canGoBack +- (BOOL)canGoBack { - return [navigationControl isEnabledForSegment: 0]; + return [navigationControl isEnabledForSegment:0]; } -- (void) setCanGoForward: (BOOL)can +- (void)setCanGoForward:(BOOL)can { - [navigationControl setEnabled: can forSegment: 1]; + [navigationControl setEnabled:can forSegment:1]; } -- (BOOL) canGoForward +- (BOOL)canGoForward { - return [navigationControl isEnabledForSegment: 1]; + return [navigationControl isEnabledForSegment:1]; } -- (void)windowDidBecomeMain: (NSNotification *)note +- (void)windowDidBecomeMain:(NSNotification *)note { - [(NetSurfApp *)NSApp setFrontTab: [[tabView selectedTabViewItem] identifier]]; + [(NetSurfApp *)NSApp setFrontTab:[[tabView selectedTabViewItem] identifier]]; } - (void)menuNeedsUpdate:(NSMenu *)menu { - if (menu == historyBackMenu) { - [activeBrowser buildBackMenu: menu]; - } else if (menu == historyForwardMenu) { - [activeBrowser buildForwardMenu: menu]; - } + if (menu == historyBackMenu) { + [activeBrowser buildBackMenu:menu]; + } else if (menu == historyForwardMenu) { + [activeBrowser buildForwardMenu:menu]; + } } #pragma mark - #pragma mark Tab bar delegate -- (void) tabView: (NSTabView *)tabView didSelectTabViewItem: (NSTabViewItem *)tabViewItem +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { - [self setActiveBrowser: [tabViewItem identifier]]; - if ([[self window] isMainWindow]) { - [(NetSurfApp *)NSApp setFrontTab: [tabViewItem identifier]]; - } + [self setActiveBrowser:[tabViewItem identifier]]; + if ([[self window] isMainWindow]) { + [(NetSurfApp *)NSApp setFrontTab:[tabViewItem identifier]]; + } } -- (BOOL)tabView:(NSTabView*)aTabView shouldDragTabViewItem:(NSTabViewItem *)tabViewItem fromTabBar:(PSMTabBarControl *)tabBarControl +- (BOOL)tabView:(NSTabView *)aTabView shouldDragTabViewItem:(NSTabViewItem *)tabViewItem fromTabBar:(PSMTabBarControl *)tabBarControl { return [aTabView numberOfTabViewItems] > 1; } -- (BOOL)tabView:(NSTabView*)aTabView shouldDropTabViewItem:(NSTabViewItem *)tabViewItem inTabBar:(PSMTabBarControl *)tabBarControl +- (BOOL)tabView:(NSTabView *)aTabView shouldDropTabViewItem:(NSTabViewItem *)tabViewItem inTabBar:(PSMTabBarControl *)tabBarControl { - [[tabViewItem identifier] setWindowController: self]; - return YES; + [[tabViewItem identifier] setWindowController:self]; + return YES; } - (PSMTabBarControl *)tabView:(NSTabView *)aTabView newTabBarForDraggedTabViewItem:(NSTabViewItem *)tabViewItem atPoint:(NSPoint)point { - BrowserWindowController *newWindow = [[BrowserWindowController alloc] init]; - [[tabViewItem identifier] setWindowController: newWindow]; - [[newWindow window] setFrameOrigin: point]; - return newWindow->tabBar; + BrowserWindowController *newWindow = [[BrowserWindowController alloc] init]; + [[tabViewItem identifier] setWindowController:newWindow]; + [[newWindow window] setFrameOrigin:point]; + return newWindow->tabBar; } -- (void) tabView: (NSTabView *)aTabView didCloseTabViewItem: (NSTabViewItem *)tabViewItem +- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem { - [tabViewItem unbind: @"label"]; - - if (activeBrowser == [tabViewItem identifier]) { - [self setActiveBrowser: nil]; - [(NetSurfApp *)NSApp setFrontTab: nil]; - } - - browser_window_destroy( [[tabViewItem identifier] browser] ); + [tabViewItem unbind:@"label"]; + + if (activeBrowser == [tabViewItem identifier]) { + [self setActiveBrowser:nil]; + [(NetSurfApp *)NSApp setFrontTab:nil]; + } + + browser_window_destroy([[tabViewItem identifier] browser]); } @end diff --git a/frontends/cocoa/DownloadWindowController.m b/frontends/cocoa/DownloadWindowController.m index 7dc461bf0..41373710c 100644 --- a/frontends/cocoa/DownloadWindowController.m +++ b/frontends/cocoa/DownloadWindowController.m @@ -34,179 +34,182 @@ - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (void)askCancelDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; -- (BOOL) receivedData: (NSData *)data; +- (BOOL)receivedData:(NSData *)data; -- (void) showError: (NSString *)error; -- (void) downloadDone; -- (void) removeIfPossible; +- (void)showError:(NSString *)error; +- (void)downloadDone; +- (void)removeIfPossible; @end -static void cocoa_unregister_download( DownloadWindowController *download ); -static void cocoa_register_download( DownloadWindowController *download ); - +static void cocoa_unregister_download(DownloadWindowController *download); +static void cocoa_register_download(DownloadWindowController *download); @implementation DownloadWindowController -- (id) initWithContext: (struct download_context *)ctx +- (id)initWithContext:(struct download_context *)ctx { - if ((self = [super initWithWindowNibName: @"DownloadWindow"]) == nil) { - return nil; - } + if ((self = [super initWithWindowNibName:@"DownloadWindow"]) == nil) { + return nil; + } - context = ctx; - totalSize = download_context_get_total_length( context ); - [self setURL: [NSURL URLWithString: [NSString stringWithUTF8String: nsurl_access(download_context_get_url( context ))]]]; - [self setMIMEType: [NSString stringWithUTF8String: download_context_get_mime_type( context )]]; - [self setStartDate: [NSDate date]]; + context = ctx; + totalSize = download_context_get_total_length(context); + [self setURL:[NSURL URLWithString:[NSString stringWithUTF8String:nsurl_access(download_context_get_url(context))]]]; + [self setMIMEType:[NSString stringWithUTF8String:download_context_get_mime_type(context)]]; + [self setStartDate:[NSDate date]]; - return self; + return self; } -- (void) dealloc +- (void)dealloc { - download_context_destroy( context ); + download_context_destroy(context); } -- (void) abort +- (void)abort { - download_context_abort( context ); - [self removeIfPossible]; + download_context_abort(context); + [self removeIfPossible]; } -- (void) askForSave +- (void)askForSave { - canClose = NO; - [[NSSavePanel savePanel] - beginSheetForDirectory: nil - file: [NSString stringWithUTF8String: download_context_get_filename( context )] - modalForWindow: [self window] - modalDelegate: self - didEndSelector: @selector(savePanelDidEnd:returnCode:contextInfo:) - contextInfo: NULL]; + canClose = NO; + [[NSSavePanel savePanel] + beginSheetForDirectory:nil + file:[NSString stringWithUTF8String:download_context_get_filename(context)] + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) + contextInfo:NULL]; } -- (void) savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - canClose = YES; - - if (returnCode == NSModalResponseCancel) { - [self abort]; - return; - } - - NSURL *targetURL = [sheet URL]; - NSString *path = [targetURL path]; - - [[NSFileManager defaultManager] createFileAtPath: path contents: nil attributes: nil]; - - FSRef ref; - if (CFURLGetFSRef( (CFURLRef)targetURL, &ref )) { - NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: - url, (NSString *)kLSQuarantineDataURLKey, - (NSString *)kLSQuarantineTypeWebDownload, (NSString *)kLSQuarantineTypeKey, - nil]; - LSSetItemAttribute( &ref, kLSRolesAll, kLSItemQuarantineProperties, (__bridge CFDictionaryRef)attributes ); - LOG("Set quarantine attributes on file %s", [path UTF8String]); - } - - [self setOutputFile: [NSFileHandle fileHandleForWritingAtPath: path]]; - [self setSaveURL: targetURL]; - - NSWindow *win = [self window]; - [win setRepresentedURL: targetURL]; - [win setTitle: [self fileName]]; + canClose = YES; - if (nil == outputFile) { - [self performSelector: @selector(showError:) withObject: @"Cannot create file" afterDelay: 0]; - return; - } - - if (nil != savedData) { - [outputFile writeData: savedData]; - [self setSavedData: nil]; - } - - [self removeIfPossible]; + if (returnCode == NSModalResponseCancel) { + [self abort]; + return; + } + + NSURL *targetURL = [sheet URL]; + NSString *path = [targetURL path]; + + [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil]; + + FSRef ref; + if (CFURLGetFSRef((CFURLRef)targetURL, &ref)) { + NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: + url, (NSString *)kLSQuarantineDataURLKey, + (NSString *)kLSQuarantineTypeWebDownload, (NSString *)kLSQuarantineTypeKey, + nil]; + LSSetItemAttribute(&ref, kLSRolesAll, kLSItemQuarantineProperties, (__bridge CFDictionaryRef)attributes); + LOG("Set quarantine attributes on file %s", [path UTF8String]); + } + + [self setOutputFile:[NSFileHandle fileHandleForWritingAtPath:path]]; + [self setSaveURL:targetURL]; + + NSWindow *win = [self window]; + [win setRepresentedURL:targetURL]; + [win setTitle:[self fileName]]; + + if (nil == outputFile) { + [self performSelector:@selector(showError:) withObject:@"Cannot create file" afterDelay:0]; + return; + } + + if (nil != savedData) { + [outputFile writeData:savedData]; + [self setSavedData:nil]; + } + + [self removeIfPossible]; } -- (BOOL) receivedData: (NSData *)data +- (BOOL)receivedData:(NSData *)data { - if (outputFile) { - [outputFile writeData: data]; - } else { - if (nil == savedData) { - [self setSavedData: [NSMutableData data]]; - } - [savedData appendData: data]; + if (outputFile) { + [outputFile writeData:data]; + } else { + if (nil == savedData) { + [self setSavedData:[NSMutableData data]]; } + [savedData appendData:data]; + } - [self setReceivedSize: receivedSize + [data length]]; + [self setReceivedSize:receivedSize + [data length]]; - return YES; + return YES; } -- (void) showError: (NSString *)error +- (void)showError:(NSString *)error { - canClose = NO; - NSAlert *alert = [NSAlert alertWithMessageText: NSLocalizedString( @"Error", @"show error" ) - defaultButton: NSLocalizedString( @"OK", @"'OK' button" ) - alternateButton: nil otherButton: nil - informativeTextWithFormat: @"%@", error]; - - [alert beginSheetModalForWindow: [self window] modalDelegate: self - didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:) - contextInfo: NULL]; + canClose = NO; + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error", @"show error") + defaultButton:NSLocalizedString(@"OK", @"'OK' button") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:@"%@", error]; + + [alert beginSheetModalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) + contextInfo:NULL]; } -- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { - [self abort]; + [self abort]; } -- (void) removeIfPossible +- (void)removeIfPossible { - if (canClose && shouldClose) { - cocoa_unregister_download( self ); - } + if (canClose && shouldClose) { + cocoa_unregister_download(self); + } } -- (void) downloadDone +- (void)downloadDone { - shouldClose = YES; - [self removeIfPossible]; + shouldClose = YES; + [self removeIfPossible]; } -- (BOOL) windowShouldClose: (id)sender +- (BOOL)windowShouldClose:(id)sender { - if ([[NSUserDefaults standardUserDefaults] boolForKey: kAlwaysCancelDownload]) { - return YES; - } - - NSAlert *ask = [NSAlert alertWithMessageText: NSLocalizedString( @"Cancel download?", @"Download" ) - defaultButton: NSLocalizedString( @"Yes", @"" ) - alternateButton: NSLocalizedString( @"No", @"" ) - otherButton: nil - informativeTextWithFormat: NSLocalizedString( @"Should the download of '%@' really be cancelled?", @"Download" ), - [self fileName]]; - [ask setShowsSuppressionButton: YES]; - [ask beginSheetModalForWindow: [self window] modalDelegate: self - didEndSelector: @selector(askCancelDidEnd:returnCode:contextInfo:) contextInfo: NULL]; - return NO; + if ([[NSUserDefaults standardUserDefaults] boolForKey:kAlwaysCancelDownload]) { + return YES; + } + + NSAlert *ask = [NSAlert alertWithMessageText:NSLocalizedString(@"Cancel download?", @"Download") + defaultButton:NSLocalizedString(@"Yes", @"") + alternateButton:NSLocalizedString(@"No", @"") + otherButton:nil + informativeTextWithFormat:NSLocalizedString(@"Should the download of '%@' really be cancelled?", @"Download"), + [self fileName]]; + [ask setShowsSuppressionButton:YES]; + [ask beginSheetModalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(askCancelDidEnd:returnCode:contextInfo:) + contextInfo:NULL]; + return NO; } -- (void) windowWillClose: (NSNotification *)notification +- (void)windowWillClose:(NSNotification *)notification { - [self abort]; + [self abort]; } -- (void) askCancelDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +- (void)askCancelDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { - if (returnCode == NSModalResponseOK) { - [[NSUserDefaults standardUserDefaults] - setBool: [[alert suppressionButton] state] == NSOnState - forKey: kAlwaysCancelDownload]; - [self close]; - } + if (returnCode == NSModalResponseOK) { + [[NSUserDefaults standardUserDefaults] + setBool:[[alert suppressionButton] state] == NSOnState + forKey:kAlwaysCancelDownload]; + [self close]; + } } #pragma mark - @@ -221,157 +224,164 @@ static void cocoa_register_download( DownloadWindowController *download ); @synthesize receivedSize; @synthesize startDate; -+ (NSSet *) keyPathsForValuesAffectingStatusText ++ (NSSet *)keyPathsForValuesAffectingStatusText { - return [NSSet setWithObjects: @"totalSize", @"receivedSize", nil]; + return [NSSet setWithObjects:@"totalSize", @"receivedSize", nil]; } #ifndef NSAppKitVersionNumber10_5 #define NSAppKitVersionNumber10_5 949 #endif -static NSString *cocoa_file_size_string( float size ) +static NSString *cocoa_file_size_string(float size) { - static unsigned factor = 0; - if (factor == 0) { - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) { - factor = 1000; - } else { - factor = 1024; - } + static unsigned factor = 0; + if (factor == 0) { + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) { + factor = 1000; + } else { + factor = 1024; } + } - if (size == 0) return @"nothing"; - if (size <= 1.0) return @"1 byte"; + if (size == 0) + return @"nothing"; + if (size <= 1.0) + return @"1 byte"; - if (size < factor - 1) return [NSString stringWithFormat:@"%1.0f bytes",size]; + if (size < factor - 1) + return [NSString stringWithFormat:@"%1.0f bytes", size]; - size /= factor; - if (size < factor - 1) return [NSString stringWithFormat:@"%1.1f KB", size]; + size /= factor; + if (size < factor - 1) + return [NSString stringWithFormat:@"%1.1f KB", size]; - size /= factor; - if (size < factor - 1) return [NSString stringWithFormat:@"%1.1f MB", size]; + size /= factor; + if (size < factor - 1) + return [NSString stringWithFormat:@"%1.1f MB", size]; - size /= factor; - if (size < factor - 1) return [NSString stringWithFormat:@"%1.1f GB", size]; + size /= factor; + if (size < factor - 1) + return [NSString stringWithFormat:@"%1.1f GB", size]; - size /= factor; - return [NSString stringWithFormat:@"%1.1f TB", size]; + size /= factor; + return [NSString stringWithFormat:@"%1.1f TB", size]; } -static NSString *cocoa_time_string( unsigned seconds ) +static NSString *cocoa_time_string(unsigned seconds) { - if (seconds <= 10) { - return NSLocalizedString(@"less than 10 seconds", - @"time remaining" ); - } - - if (seconds < 60) { - return [NSString stringWithFormat: NSLocalizedString( @"%u seconds", - @"time remaining" ), seconds]; - } - - unsigned minutes = seconds / 60; - seconds = seconds % 60; - - if (minutes < 60) { - return [NSString stringWithFormat: NSLocalizedString( @"%u:%02u minutes", - @"time remaining: minutes, seconds" ) , minutes, seconds]; - } - - unsigned hours = minutes / 60; - minutes = minutes % 60; - - return [NSString stringWithFormat: NSLocalizedString( @"%2:%02u hours", @"time remaining: hours, minutes" ), hours, minutes]; + if (seconds <= 10) { + return NSLocalizedString(@"less than 10 seconds", + @"time remaining"); + } + + if (seconds < 60) { + return [NSString stringWithFormat:NSLocalizedString(@"%u seconds", + @"time remaining"), + seconds]; + } + + unsigned minutes = seconds / 60; + seconds = seconds % 60; + + if (minutes < 60) { + return [NSString stringWithFormat:NSLocalizedString(@"%u:%02u minutes", + @"time remaining: minutes, seconds"), + minutes, seconds]; + } + + unsigned hours = minutes / 60; + minutes = minutes % 60; + + return [NSString stringWithFormat:NSLocalizedString(@"%2:%02u hours", @"time remaining: hours, minutes"), hours, minutes]; } -- (NSString *) statusText +- (NSString *)statusText { - NSString *speedString = @""; - - float speed = 0.0; - NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate: startDate]; - if (elapsedTime >= 0.1) { - speed = (float)receivedSize / elapsedTime; - speedString = [NSString stringWithFormat: @" (%@/s)", cocoa_file_size_string( speed )]; - } - - NSString *timeRemainingString = @""; - NSString *totalSizeString = @""; - if (totalSize != 0) { - if (speed > 0.0) { - float timeRemaining = (float)(totalSize - receivedSize) / speed; - timeRemainingString = [NSString stringWithFormat: @": %@", cocoa_time_string( timeRemaining )]; - } - totalSizeString = [NSString stringWithFormat: NSLocalizedString( @" of %@", @"... of (total size)" ), cocoa_file_size_string( totalSize )]; + NSString *speedString = @""; + + float speed = 0.0; + NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate]; + if (elapsedTime >= 0.1) { + speed = (float)receivedSize / elapsedTime; + speedString = [NSString stringWithFormat:@" (%@/s)", cocoa_file_size_string(speed)]; + } + + NSString *timeRemainingString = @""; + NSString *totalSizeString = @""; + if (totalSize != 0) { + if (speed > 0.0) { + float timeRemaining = (float)(totalSize - receivedSize) / speed; + timeRemainingString = [NSString stringWithFormat:@": %@", cocoa_time_string(timeRemaining)]; } + totalSizeString = [NSString stringWithFormat:NSLocalizedString(@" of %@", @"... of (total size)"), cocoa_file_size_string(totalSize)]; + } - return [NSString stringWithFormat: @"%@%@%@%@", cocoa_file_size_string( receivedSize ), - totalSizeString, speedString, timeRemainingString]; + return [NSString stringWithFormat:@"%@%@%@%@", cocoa_file_size_string(receivedSize), + totalSizeString, speedString, timeRemainingString]; } -+ (NSSet *) keyPathsForValuesAffectingFileName ++ (NSSet *)keyPathsForValuesAffectingFileName { - return [NSSet setWithObject: @"saveURL"]; + return [NSSet setWithObject:@"saveURL"]; } -- (NSString *) fileName +- (NSString *)fileName { - return [[saveURL path] lastPathComponent]; + return [[saveURL path] lastPathComponent]; } -+ (NSSet *) keyPathsForValuesAffectingIcon ++ (NSSet *)keyPathsForValuesAffectingIcon { - return [NSSet setWithObjects: @"mimeType", @"URL", nil]; + return [NSSet setWithObjects:@"mimeType", @"URL", nil]; } -- (NSImage *) icon +- (NSImage *)icon { - NSString *type = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag( kUTTagClassMIMEType, (__bridge CFStringRef)mimeType, NULL ); - if ([type hasPrefix: @"dyn."] || [type isEqualToString: (NSString *)kUTTypeData]) { - NSString *pathExt = [[url path] pathExtension]; - type = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, (__bridge CFStringRef)pathExt, NULL ); - } - return [[NSWorkspace sharedWorkspace] iconForFileType: type]; + NSString *type = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mimeType, NULL); + if ([type hasPrefix:@"dyn."] || [type isEqualToString:(NSString *)kUTTypeData]) { + NSString *pathExt = [[url path] pathExtension]; + type = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)pathExt, NULL); + } + return [[NSWorkspace sharedWorkspace] iconForFileType:type]; } - #pragma mark - #pragma mark NetSurf interface functions static struct gui_download_window * gui_download_window_create(download_context *ctx, - struct gui_window *parent) + struct gui_window *parent) { - DownloadWindowController * const window = [[DownloadWindowController alloc] initWithContext: ctx]; - cocoa_register_download( window ); - [window askForSave]; + DownloadWindowController *const window = [[DownloadWindowController alloc] initWithContext:ctx]; + cocoa_register_download(window); + [window askForSave]; - return (__bridge_retained struct gui_download_window *)window; + return (__bridge_retained struct gui_download_window *)window; } static nserror gui_download_window_data(struct gui_download_window *dw, - const char *data, - unsigned int size) + const char *data, + unsigned int size) { - DownloadWindowController * const window = (__bridge DownloadWindowController *)dw; - return [window receivedData: [NSData dataWithBytes: data length: size]] ? NSERROR_OK : NSERROR_SAVE_FAILED; + DownloadWindowController *const window = (__bridge DownloadWindowController *)dw; + return [window receivedData:[NSData dataWithBytes:data length:size]] ? NSERROR_OK : NSERROR_SAVE_FAILED; } static void gui_download_window_error(struct gui_download_window *dw, - const char *error_msg) + const char *error_msg) { - DownloadWindowController * const window = (__bridge DownloadWindowController *)dw; - [window showError: [NSString stringWithUTF8String: error_msg]]; + DownloadWindowController *const window = (__bridge DownloadWindowController *)dw; + [window showError:[NSString stringWithUTF8String:error_msg]]; } static void gui_download_window_done(struct gui_download_window *dw) { - DownloadWindowController * const window = (__bridge DownloadWindowController *)dw; - [window downloadDone]; + DownloadWindowController *const window = (__bridge DownloadWindowController *)dw; + [window downloadDone]; } @end @@ -380,26 +390,25 @@ gui_download_window_done(struct gui_download_window *dw) static NSMutableSet *cocoa_all_downloads = nil; static void -cocoa_register_download( DownloadWindowController *download ) +cocoa_register_download(DownloadWindowController *download) { - if (cocoa_all_downloads == nil) { - cocoa_all_downloads = [[NSMutableSet alloc] init]; - } - [cocoa_all_downloads addObject: download]; + if (cocoa_all_downloads == nil) { + cocoa_all_downloads = [[NSMutableSet alloc] init]; + } + [cocoa_all_downloads addObject:download]; } static void -cocoa_unregister_download( DownloadWindowController *download ) +cocoa_unregister_download(DownloadWindowController *download) { - [cocoa_all_downloads removeObject: download]; + [cocoa_all_downloads removeObject:download]; } - static struct gui_download_table download_table = { - .create = gui_download_window_create, - .data = gui_download_window_data, - .error = gui_download_window_error, - .done = gui_download_window_done, + .create = gui_download_window_create, + .data = gui_download_window_data, + .error = gui_download_window_error, + .done = gui_download_window_done, }; struct gui_download_table *cocoa_download_table = &download_table; diff --git a/frontends/cocoa/FormSelectMenu.m b/frontends/cocoa/FormSelectMenu.m index a29d00811..e089b0f59 100644 --- a/frontends/cocoa/FormSelectMenu.m +++ b/frontends/cocoa/FormSelectMenu.m @@ -23,81 +23,80 @@ #import "netsurf/browser_window.h" #import "netsurf/form.h" -static inline NSRect cocoa_rect_for_control( struct browser_window *bw, struct form_control *control) +static inline NSRect cocoa_rect_for_control(struct browser_window *bw, struct form_control *control) { struct rect r; form_control_bounding_rect(control, &r); return cocoa_scaled_rect(browser_window_get_scale(bw), - r.x0, - r.y0, - r.x1, - r.y1); + r.x0, + r.y0, + r.x1, + r.y1); } @interface FormSelectMenu () -- (void) itemSelected: (id) sender; +- (void)itemSelected:(id)sender; @end - @implementation FormSelectMenu -- (id) initWithControl: (struct form_control *) c forWindow: (struct browser_window *) w +- (id)initWithControl:(struct form_control *)c forWindow:(struct browser_window *)w { - if ((self = [super init]) == nil) return nil; + if ((self = [super init]) == nil) + return nil; control = c; browser = w; - menu = [[NSMenu alloc] initWithTitle: @"Select"]; + menu = [[NSMenu alloc] initWithTitle:@"Select"]; if (menu == nil) { return nil; } - [menu addItemWithTitle: @"" action: NULL keyEquivalent: @""]; + [menu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; NSInteger currentItemIndex = 0; struct form_option *opt; for (opt = form_select_get_option(control, 0); opt != NULL; opt = opt->next) { - NSMenuItem *item = [[NSMenuItem alloc] initWithTitle: [NSString stringWithUTF8String: opt->text] - action: @selector( itemSelected: ) - keyEquivalent: @""]; + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:opt->text] + action:@selector(itemSelected:) + keyEquivalent:@""]; if (opt->selected) { - [item setState: NSOnState]; + [item setState:NSOnState]; } - [item setTarget: self]; - [item setTag: currentItemIndex++]; - [menu addItem: item]; + [item setTarget:self]; + [item setTag:currentItemIndex++]; + [menu addItem:item]; } - [menu setDelegate: self]; + [menu setDelegate:self]; return self; } - -- (void) runInView: (NSView *) view +- (void)runInView:(NSView *)view { - (void)(__bridge_retained void *)self; + (void)(__bridge_retained void *) self; - cell = [[NSPopUpButtonCell alloc] initTextCell: @"" pullsDown: YES]; - [cell setMenu: menu]; + cell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:YES]; + [cell setMenu:menu]; const NSRect rect = cocoa_rect_for_control(browser, control); - [cell attachPopUpWithFrame: rect inView: view]; - [cell performClickWithFrame: rect inView: view]; + [cell attachPopUpWithFrame:rect inView:view]; + [cell performClickWithFrame:rect inView:view]; } -- (void) itemSelected: (id) sender +- (void)itemSelected:(id)sender { - form_select_process_selection( control, (int)[sender tag] ); + form_select_process_selection(control, (int)[sender tag]); } -- (void) menuDidClose: (NSMenu *) sender +- (void)menuDidClose:(NSMenu *)sender { (void)(__bridge_transfer id)((__bridge void *)self); } diff --git a/frontends/cocoa/HistoryView.m b/frontends/cocoa/HistoryView.m index 00a7d4abc..94d526123 100644 --- a/frontends/cocoa/HistoryView.m +++ b/frontends/cocoa/HistoryView.m @@ -30,116 +30,117 @@ @synthesize browser = browserView; -- (void) setBrowser: (BrowserView *) bw +- (void)setBrowser:(BrowserView *)bw { - browserView = bw; - browser = [bw browser]; - [self updateHistory]; + browserView = bw; + browser = [bw browser]; + [self updateHistory]; } -- (NSSize) size +- (NSSize)size { - int width, height; - browser_window_history_size( browser, &width, &height ); - - return cocoa_size( width, height ); + int width, height; + browser_window_history_size(browser, &width, &height); + + return cocoa_size(width, height); } -- (void) updateHistory +- (void)updateHistory { - [self setFrameSize: [self size]]; - [self setNeedsDisplay: YES]; + [self setFrameSize:[self size]]; + [self setNeedsDisplay:YES]; } -- (void) drawRect: (NSRect)rect +- (void)drawRect:(NSRect)rect { - [[NSColor clearColor] set]; - [NSBezierPath fillRect: rect]; - - struct redraw_context ctx = { - .interactive = true, - .background_images = true, - .plot = &cocoa_plotters - }; - - cocoa_set_clip( rect ); - - browser_window_history_redraw( browser, &ctx ); + [[NSColor clearColor] set]; + [NSBezierPath fillRect:rect]; + + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &cocoa_plotters + }; + + cocoa_set_clip(rect); + + browser_window_history_redraw(browser, &ctx); } -- (void) mouseUp: (NSEvent *)theEvent +- (void)mouseUp:(NSEvent *)theEvent { - const NSPoint location = [self convertPoint: [theEvent locationInWindow] fromView: nil]; - const bool newWindow = [theEvent modifierFlags] & NSEventModifierFlagCommand; - if (browser_window_history_click( browser, - cocoa_pt_to_px( location.x ), cocoa_pt_to_px( location.y ), - newWindow )) { - [browserView setHistoryVisible: NO]; - } + const NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + const bool newWindow = [theEvent modifierFlags] & NSEventModifierFlagCommand; + if (browser_window_history_click(browser, + cocoa_pt_to_px(location.x), cocoa_pt_to_px(location.y), + newWindow)) { + [browserView setHistoryVisible:NO]; + } } -- (BOOL) isFlipped +- (BOOL)isFlipped { - return YES; + return YES; } -- (void) mouseEntered: (NSEvent *) event +- (void)mouseEntered:(NSEvent *)event { - [[NSCursor pointingHandCursor] set]; + [[NSCursor pointingHandCursor] set]; } -- (void) mouseExited: (NSEvent *) event +- (void)mouseExited:(NSEvent *)event { - [[NSCursor arrowCursor] set]; + [[NSCursor arrowCursor] set]; } -static bool cursor_rects_cb( const struct browser_window *bw, int x0, int y0, int x1, int y1, - const struct history_entry *page, void *user_data ) +static bool cursor_rects_cb(const struct browser_window *bw, int x0, int y0, int x1, int y1, + const struct history_entry *page, void *user_data) { - HistoryView *view = (__bridge HistoryView *)user_data; - - NSRect rect = NSIntersectionRect( [view visibleRect], cocoa_rect( x0, y0, x1, y1 ) ); - if (!NSIsEmptyRect( rect )) { - - NSString *toolTip = [NSString stringWithFormat: @"%s\n%s", browser_window_history_entry_get_title(page), - browser_window_history_entry_get_url( page )]; - - [view addToolTipRect: rect owner: toolTip userData: nil]; - NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: rect - options: NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp - owner: view userInfo: nil]; - [view addTrackingArea: area]; - } - - return true; + HistoryView *view = (__bridge HistoryView *)user_data; + + NSRect rect = NSIntersectionRect([view visibleRect], cocoa_rect(x0, y0, x1, y1)); + if (!NSIsEmptyRect(rect)) { + + NSString *toolTip = [NSString stringWithFormat:@"%s\n%s", browser_window_history_entry_get_title(page), + browser_window_history_entry_get_url(page)]; + + [view addToolTipRect:rect owner:toolTip userData:nil]; + NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:rect + options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp + owner:view + userInfo:nil]; + [view addTrackingArea:area]; + } + + return true; } -- (NSToolTipTag)addToolTipRect: (NSRect) rect owner: (id) owner userData: (void *) userData +- (NSToolTipTag)addToolTipRect:(NSRect)rect owner:(id)owner userData:(void *)userData { - if (toolTips == nil) toolTips = [[NSMutableArray alloc] init]; - [toolTips addObject: owner]; - - return [super addToolTipRect: rect owner: owner userData: userData]; + if (toolTips == nil) + toolTips = [[NSMutableArray alloc] init]; + [toolTips addObject:owner]; + + return [super addToolTipRect:rect owner:owner userData:userData]; } -- (void) removeAllToolTips +- (void)removeAllToolTips { - [super removeAllToolTips]; - [toolTips removeAllObjects]; + [super removeAllToolTips]; + [toolTips removeAllObjects]; } -- (void) updateTrackingAreas +- (void)updateTrackingAreas { - [self removeAllToolTips]; - - for (NSTrackingArea *area in [self trackingAreas]) { - [self removeTrackingArea: area]; - } - - browser_window_history_enumerate( browser, cursor_rects_cb, (__bridge void *)self ); - - [super updateTrackingAreas]; -} + [self removeAllToolTips]; + for (NSTrackingArea *area in [self trackingAreas]) { + [self removeTrackingArea:area]; + } + + browser_window_history_enumerate(browser, cursor_rects_cb, (__bridge void *)self); + + [super updateTrackingAreas]; +} @end diff --git a/frontends/cocoa/HistoryWindowController.m b/frontends/cocoa/HistoryWindowController.m index aff85f2d5..1a30bb573 100644 --- a/frontends/cocoa/HistoryWindowController.m +++ b/frontends/cocoa/HistoryWindowController.m @@ -28,17 +28,18 @@ - (instancetype)init { - if ((self = [super initWithWindowNibName: @"HistoryWindow"]) == nil) return nil; - - tree = [[Tree alloc] initWithFlags: TREE_HISTORY]; - - return self; + if ((self = [super initWithWindowNibName:@"HistoryWindow"]) == nil) + return nil; + + tree = [[Tree alloc] initWithFlags:TREE_HISTORY]; + + return self; } - (void)awakeFromNib { - [view setTree: tree]; - [[self window] setExcludedFromWindowsMenu: YES]; + [view setTree:tree]; + [[self window] setExcludedFromWindowsMenu:YES]; } @end diff --git a/frontends/cocoa/LocalHistoryController.m b/frontends/cocoa/LocalHistoryController.m index 97c592d43..805539669 100644 --- a/frontends/cocoa/LocalHistoryController.m +++ b/frontends/cocoa/LocalHistoryController.m @@ -27,93 +27,94 @@ @synthesize browser; @synthesize history; -- (instancetype)initWithBrowser: (BrowserView *) bw +- (instancetype)initWithBrowser:(BrowserView *)bw { - if ((self = [super initWithWindowNibName: @"LocalHistoryPanel"]) == nil) return nil; - - browser = bw; - - return self; + if ((self = [super initWithWindowNibName:@"LocalHistoryPanel"]) == nil) + return nil; + + browser = bw; + + return self; } -- (void) attachToView: (NSView *) view +- (void)attachToView:(NSView *)view { - NSDisableScreenUpdates(); - - ArrowWindow *box = (ArrowWindow *)[self window]; - - [box setContentSize: [history size]]; - [box setArrowPosition: 50]; - [history updateHistory]; - [box attachToView: view]; - - NSRect frame = [box frame]; - NSRect screenFrame = [[box screen] visibleFrame]; - - const CGFloat arrowSize = [box arrowSize]; - frame.origin.x += arrowSize; - frame.origin.y += arrowSize; - frame.size.width -= 2 * arrowSize; - frame.size.height -= 2 * arrowSize; - - if (NSMinY( frame ) < NSMinY( screenFrame )) { - const CGFloat delta = NSMinY( screenFrame ) - NSMinY( frame ); - frame.size.height -= delta; - frame.origin.y += delta; - } - - CGFloat arrowPositionChange = 50; - if (NSMaxX( frame ) > NSMaxX( screenFrame )) { - const CGFloat delta = NSMaxX( frame ) - NSMaxX( screenFrame ); - arrowPositionChange += delta; - frame.origin.x -= delta; - } - - if (NSMinX( frame ) < NSMinX( screenFrame )) { - const CGFloat delta = NSMinX( screenFrame ) - NSMinX( frame ); - arrowPositionChange -= delta; - frame.origin.x += delta; - frame.size.width -= delta; - } - - frame.origin.x -= arrowSize; - frame.origin.y -= arrowSize; - frame.size.width += 2 * arrowSize; - frame.size.height += 2 * arrowSize; - - [box setArrowPosition: arrowPositionChange]; - [box setFrame: frame display: YES]; - - NSEnableScreenUpdates(); + NSDisableScreenUpdates(); + + ArrowWindow *box = (ArrowWindow *)[self window]; + + [box setContentSize:[history size]]; + [box setArrowPosition:50]; + [history updateHistory]; + [box attachToView:view]; + + NSRect frame = [box frame]; + NSRect screenFrame = [[box screen] visibleFrame]; + + const CGFloat arrowSize = [box arrowSize]; + frame.origin.x += arrowSize; + frame.origin.y += arrowSize; + frame.size.width -= 2 * arrowSize; + frame.size.height -= 2 * arrowSize; + + if (NSMinY(frame) < NSMinY(screenFrame)) { + const CGFloat delta = NSMinY(screenFrame) - NSMinY(frame); + frame.size.height -= delta; + frame.origin.y += delta; + } + + CGFloat arrowPositionChange = 50; + if (NSMaxX(frame) > NSMaxX(screenFrame)) { + const CGFloat delta = NSMaxX(frame) - NSMaxX(screenFrame); + arrowPositionChange += delta; + frame.origin.x -= delta; + } + + if (NSMinX(frame) < NSMinX(screenFrame)) { + const CGFloat delta = NSMinX(screenFrame) - NSMinX(frame); + arrowPositionChange -= delta; + frame.origin.x += delta; + frame.size.width -= delta; + } + + frame.origin.x -= arrowSize; + frame.origin.y -= arrowSize; + frame.size.width += 2 * arrowSize; + frame.size.height += 2 * arrowSize; + + [box setArrowPosition:arrowPositionChange]; + [box setFrame:frame display:YES]; + + NSEnableScreenUpdates(); } -- (void) detach +- (void)detach { - [(ArrowWindow *)[self window] detach]; + [(ArrowWindow *)[self window] detach]; } -- (void) windowDidLoad +- (void)windowDidLoad { - [history setBrowser: browser]; + [history setBrowser:browser]; } -- (void) redraw +- (void)redraw { - [history setNeedsDisplay: YES]; + [history setNeedsDisplay:YES]; } -- (void) keyDown: (NSEvent *)theEvent +- (void)keyDown:(NSEvent *)theEvent { - unichar key = [[theEvent characters] characterAtIndex: 0]; - switch (key) { - case 27: - [browser setHistoryVisible: NO]; - break; - - default: - NSBeep(); - break; - }; + unichar key = [[theEvent characters] characterAtIndex:0]; + switch (key) { + case 27: + [browser setHistoryVisible:NO]; + break; + + default: + NSBeep(); + break; + }; } @end diff --git a/frontends/cocoa/NetSurfAppDelegate.m b/frontends/cocoa/NetSurfAppDelegate.m index e9e5b4376..55cd714f0 100644 --- a/frontends/cocoa/NetSurfAppDelegate.m +++ b/frontends/cocoa/NetSurfAppDelegate.m @@ -28,173 +28,171 @@ #import "cocoa/PreferencesWindowController.h" #import "cocoa/HistoryWindowController.h" - @interface NetSurfAppDelegate () - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; @end - @implementation NetSurfAppDelegate @synthesize history; @synthesize search; @synthesize preferences; -- (void) newDocument: (id) sender +- (void)newDocument:(id)sender { - nsurl *url; - nserror error; - - if (nsoption_charp(homepage_url) != NULL) { - error = nsurl_create(nsoption_charp(homepage_url), &url); - } else { - error = nsurl_create(NETSURF_HOMEPAGE, &url); - } - - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + nsurl *url; + nserror error; + + if (nsoption_charp(homepage_url) != NULL) { + error = nsurl_create(nsoption_charp(homepage_url), &url); + } else { + error = nsurl_create(NETSURF_HOMEPAGE, &url); + } + + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (void) openDocument: (id) sender +- (void)openDocument:(id)sender { - nsurl *u; - nserror error; - - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; - [openPanel setAllowsMultipleSelection: YES]; - if ([openPanel runModalForTypes: nil] == NSModalResponseOK) { - for (NSURL *url in [openPanel URLs]) { - error = nsurl_create([[url absoluteString] UTF8String], &u); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - u, - NULL, - NULL, - NULL); - nsurl_unref(u); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } - } - } + nsurl *u; + nserror error; + + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + [openPanel setAllowsMultipleSelection:YES]; + if ([openPanel runModalForTypes:nil] == NSModalResponseOK) { + for (NSURL *url in [openPanel URLs]) { + error = nsurl_create([[url absoluteString] UTF8String], &u); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + u, + NULL, + NULL, + NULL); + nsurl_unref(u); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } + } + } } - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { - nsurl *url; - nserror error; - NSString *urlAsString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; - - error = nsurl_create([urlAsString UTF8String], &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + nsurl *url; + nserror error; + NSString *urlAsString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + + error = nsurl_create([urlAsString UTF8String], &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } } -- (IBAction) showSearchWindow: (id) sender +- (IBAction)showSearchWindow:(id)sender { - if (search == nil) { - [self setSearch: [[SearchWindowController alloc] init]]; - } - [[search window] makeKeyAndOrderFront: self]; + if (search == nil) { + [self setSearch:[[SearchWindowController alloc] init]]; + } + [[search window] makeKeyAndOrderFront:self]; } -- (IBAction) searchForward: (id) sender +- (IBAction)searchForward:(id)sender { - [search search: SearchForward]; + [search search:SearchForward]; } -- (IBAction) searchBackward: (id) sender +- (IBAction)searchBackward:(id)sender { - [search search: SearchBackward]; + [search search:SearchBackward]; } -- (BOOL) validateMenuItem: (id) item +- (BOOL)validateMenuItem:(id)item { - SEL action = [item action]; - - if (action == @selector( searchForward: )) { - return [search canGoForward]; - } else if (action == @selector( searchBackward: )) { - return [search canGoBack]; - } - - return YES; + SEL action = [item action]; + + if (action == @selector(searchForward:)) { + return [search canGoForward]; + } else if (action == @selector(searchBackward:)) { + return [search canGoBack]; + } + + return YES; } -- (IBAction) showPreferences: (id) sender +- (IBAction)showPreferences:(id)sender { - if (preferences == nil) { - [self setPreferences: [[PreferencesWindowController alloc] init]]; - } - [preferences showWindow: sender]; + if (preferences == nil) { + [self setPreferences:[[PreferencesWindowController alloc] init]]; + } + [preferences showWindow:sender]; } -- (IBAction) showGlobalHistory: (id) sender +- (IBAction)showGlobalHistory:(id)sender { - if (history == nil) { - [self setHistory: [[HistoryWindowController alloc] init] ]; - } - [history showWindow: sender]; + if (history == nil) { + [self setHistory:[[HistoryWindowController alloc] init]]; + } + [history showWindow:sender]; } // Application delegate methods -- (BOOL) applicationOpenUntitledFile: (NSApplication *)sender +- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender { - [self newDocument: self]; - return YES; + [self newDocument:self]; + return YES; } --(void)applicationWillFinishLaunching:(NSNotification *)aNotification +- (void)applicationWillFinishLaunching:(NSNotification *)aNotification { NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; - [appleEventManager setEventHandler:self + [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) - forEventClass:kInternetEventClass andEventID:kAEGetURL]; + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; } - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { - nsurl *url; - nserror error; - NSURL *urltxt = [NSURL fileURLWithPath: filename]; - - error = nsurl_create([[urltxt absoluteString] UTF8String], &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } - - return YES; + nsurl *url; + nserror error; + NSURL *urltxt = [NSURL fileURLWithPath:filename]; + + error = nsurl_create([[urltxt absoluteString] UTF8String], &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } + + return YES; } - @end diff --git a/frontends/cocoa/NetsurfApp.m b/frontends/cocoa/NetsurfApp.m index 1ecdc51a7..4c5442a2d 100644 --- a/frontends/cocoa/NetsurfApp.m +++ b/frontends/cocoa/NetsurfApp.m @@ -59,158 +59,153 @@ static bool cocoa_done = false; * * \param error The message to display to the user. */ -static void die(const char * const error) +static void die(const char *const error) { - [NSException raise: @"NetsurfDie" format: @"Error: %s", error]; + [NSException raise:@"NetsurfDie" format:@"Error: %s", error]; } -- (void) loadOptions +- (void)loadOptions { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: - cocoa_get_user_path( @"Cookies" ), - kCookiesFileOption, - cocoa_get_user_path( @"URLs" ), - kURLsFileOption, - [NSString stringWithUTF8String: NETSURF_HOMEPAGE], - kHomepageURLOption, - nil]]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: + cocoa_get_user_path(@"Cookies"), + kCookiesFileOption, + cocoa_get_user_path(@"URLs"), + kURLsFileOption, + [NSString stringWithUTF8String:NETSURF_HOMEPAGE], + kHomepageURLOption, + nil]]; + nsoption_setnull_charp(cookie_file, strdup([[defaults objectForKey:kCookiesFileOption] UTF8String])); - nsoption_setnull_charp(cookie_file, strdup( [[defaults objectForKey: kCookiesFileOption] UTF8String] )); + nsoption_setnull_charp(cookie_jar, strdup(nsoption_charp(cookie_file))); - nsoption_setnull_charp(cookie_jar, strdup( nsoption_charp(cookie_file) )); + nsoption_setnull_charp(homepage_url, strdup([[defaults objectForKey:kHomepageURLOption] UTF8String])); - nsoption_setnull_charp(homepage_url, strdup( [[defaults objectForKey: kHomepageURLOption] UTF8String] )); + urldb_load([[defaults objectForKey:kURLsFileOption] UTF8String]); + urldb_load_cookies(nsoption_charp(cookie_file)); - urldb_load( [[defaults objectForKey: kURLsFileOption] UTF8String] ); - urldb_load_cookies( nsoption_charp(cookie_file) ); - - cocoa_update_scale_factor(); - LOG("done setup"); + cocoa_update_scale_factor(); + LOG("done setup"); } -- (void) saveOptions +- (void)saveOptions { - urldb_save_cookies( nsoption_charp(cookie_file) ); - urldb_save( [[[NSUserDefaults standardUserDefaults] objectForKey: kURLsFileOption] UTF8String] ); + urldb_save_cookies(nsoption_charp(cookie_file)); + urldb_save([[[NSUserDefaults standardUserDefaults] objectForKey:kURLsFileOption] UTF8String]); } -- (void) run +- (void)run { @autoreleasepool { - @autoreleasepool { - [self finishLaunching]; + [self finishLaunching]; - [self loadOptions]; + [self loadOptions]; } while (!cocoa_done) { @autoreleasepool { - NSEvent *event = - [self nextEventMatchingMask: NSEventMaskAny - untilDate: [NSDate distantFuture] - inMode: NSDefaultRunLoopMode - dequeue: YES]; + [self nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; if (nil != event) { - [self sendEvent: event]; - [self updateWindows]; + [self sendEvent:event]; + [self updateWindows]; } } - } [self saveOptions]; - } } --(void) terminate: (id)sender +- (void)terminate:(id)sender { - [[NSNotificationCenter defaultCenter] postNotificationName:NSApplicationWillTerminateNotification object:self]; - - cocoa_done = true; - [self postEvent: [NSEvent otherEventWithType: NSEventTypeApplicationDefined - location: NSZeroPoint - modifierFlags: 0 - timestamp: 0 - windowNumber: 0 - context: NULL - subtype: 0 - data1: 0 - data2: 0] - atStart: YES]; + [[NSNotificationCenter defaultCenter] postNotificationName:NSApplicationWillTerminateNotification object:self]; + + cocoa_done = true; + [self postEvent:[NSEvent otherEventWithType:NSEventTypeApplicationDefined + location:NSZeroPoint + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:NULL + subtype:0 + data1:0 + data2:0] + atStart:YES]; } @end #pragma mark - -static NSString *cocoa_get_preferences_path( void ) +static NSString *cocoa_get_preferences_path(void) { - NSArray *paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSUserDomainMask, YES ); - NSCAssert( [paths count] >= 1, @"Where is the application support directory?" ); + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSCAssert([paths count] >= 1, @"Where is the application support directory?"); - NSString *netsurfPath = [[paths objectAtIndex: 0] stringByAppendingPathComponent: @"NetSurf"]; + NSString *netsurfPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"NetSurf"]; - NSFileManager *fm = [NSFileManager defaultManager]; - BOOL isDirectory = NO; - BOOL exists = [fm fileExistsAtPath: netsurfPath isDirectory: &isDirectory]; + NSFileManager *fm = [NSFileManager defaultManager]; + BOOL isDirectory = NO; + BOOL exists = [fm fileExistsAtPath:netsurfPath isDirectory:&isDirectory]; - if (!exists) { - exists = [fm createDirectoryAtPath: netsurfPath withIntermediateDirectories: YES attributes: nil error: NULL]; - isDirectory = YES; - } - if (!(exists && isDirectory)) { - die( "Cannot create netsurf preferences directory" ); - } + if (!exists) { + exists = [fm createDirectoryAtPath:netsurfPath withIntermediateDirectories:YES attributes:nil error:NULL]; + isDirectory = YES; + } + if (!(exists && isDirectory)) { + die("Cannot create netsurf preferences directory"); + } - return netsurfPath; + return netsurfPath; } -NSString *cocoa_get_user_path( NSString *fileName ) +NSString *cocoa_get_user_path(NSString *fileName) { - return [cocoa_get_preferences_path() stringByAppendingPathComponent: fileName]; + return [cocoa_get_preferences_path() stringByAppendingPathComponent:fileName]; } -static const char *cocoa_get_options_file( void ) +static const char *cocoa_get_options_file(void) { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: - cocoa_get_user_path( @"Options" ), kOptionsFileOption, - nil]]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: + cocoa_get_user_path(@"Options"), kOptionsFileOption, + nil]]; - return [[defaults objectForKey: kOptionsFileOption] UTF8String]; + return [[defaults objectForKey:kOptionsFileOption] UTF8String]; } -static NSApplication *cocoa_prepare_app( void ) +static NSApplication *cocoa_prepare_app(void) { - /* if application instance has already been created return it */ - if (NSApp != nil) { - return NSApp; - } + /* if application instance has already been created return it */ + if (NSApp != nil) { + return NSApp; + } - NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; - /* Obtain principle class of bundle which must implement sharedApplication API */ - Class principalClass = NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]); - NSCAssert([principalClass respondsToSelector:@selector(sharedApplication)], - @"Principal class must implement sharedApplication."); + /* Obtain principle class of bundle which must implement sharedApplication API */ + Class principalClass = NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]); + NSCAssert([principalClass respondsToSelector:@selector(sharedApplication)], + @"Principal class must implement sharedApplication."); - /* create application instance */ - [principalClass sharedApplication]; + /* create application instance */ + [principalClass sharedApplication]; - /* load interface nib */ - NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"]; - NSNib *mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]]; - [mainNib instantiateNibWithOwner:NSApp topLevelObjects:nil]; + /* load interface nib */ + NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"]; + NSNib *mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]]; + [mainNib instantiateNibWithOwner:NSApp topLevelObjects:nil]; - return NSApp; + return NSApp; } /** @@ -221,87 +216,87 @@ static NSApplication *cocoa_prepare_app( void ) */ static nserror set_defaults(struct nsoption_s *defaults) { - /* Set defaults for absent option strings */ - const char * const ca_bundle = [[[NSBundle mainBundle] pathForResource: @"ca-bundle" ofType: @""] UTF8String]; + /* Set defaults for absent option strings */ + const char *const ca_bundle = [[[NSBundle mainBundle] pathForResource:@"ca-bundle" ofType:@""] UTF8String]; - nsoption_setnull_charp(ca_bundle, strdup(ca_bundle)); + nsoption_setnull_charp(ca_bundle, strdup(ca_bundle)); - return NSERROR_OK; + return NSERROR_OK; } -int main( int argc, char **argv ) +int main(int argc, char **argv) { - nsurl *url; - nserror error; - struct netsurf_table cocoa_table = { - .misc = cocoa_misc_table, - .window = cocoa_window_table, - .clipboard = cocoa_clipboard_table, - .download = cocoa_download_table, - .fetch = cocoa_fetch_table, - .search = cocoa_search_table, - .bitmap = cocoa_bitmap_table, - .layout = cocoa_layout_table, - }; - - error = netsurf_register(&cocoa_table); - if (error != NSERROR_OK) { - die("NetSurf operation table failed registration"); - } + nsurl *url; + nserror error; + struct netsurf_table cocoa_table = { + .misc = cocoa_misc_table, + .window = cocoa_window_table, + .clipboard = cocoa_clipboard_table, + .download = cocoa_download_table, + .fetch = cocoa_fetch_table, + .search = cocoa_search_table, + .bitmap = cocoa_bitmap_table, + .layout = cocoa_layout_table, + }; + + error = netsurf_register(&cocoa_table); + if (error != NSERROR_OK) { + die("NetSurf operation table failed registration"); + } - const char * const messages = [[[NSBundle mainBundle] pathForResource: @"Messages" ofType: @""] UTF8String]; - const char * const options = cocoa_get_options_file(); + const char *const messages = [[[NSBundle mainBundle] pathForResource:@"Messages" ofType:@""] UTF8String]; + const char *const options = cocoa_get_options_file(); - /* initialise logging. Not fatal if it fails but not much we + /* initialise logging. Not fatal if it fails but not much we * can do about it either. */ - nslog_init(NULL, &argc, argv); + nslog_init(NULL, &argc, argv); - /* user options setup */ - error = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); - if (error != NSERROR_OK) { - die("Options failed to initialise"); - } - nsoption_read(options, NULL); - nsoption_commandline(&argc, argv, NULL); + /* user options setup */ + error = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + if (error != NSERROR_OK) { + die("Options failed to initialise"); + } + nsoption_read(options, NULL); + nsoption_commandline(&argc, argv, NULL); - error = messages_add_from_file(messages); + error = messages_add_from_file(messages); - /* common initialisation */ - error = netsurf_init(NULL); - if (error != NSERROR_OK) { - die("NetSurf failed to initialise"); - } + /* common initialisation */ + error = netsurf_init(NULL); + if (error != NSERROR_OK) { + die("NetSurf failed to initialise"); + } - /* Initialise filename allocator */ - filename_initialise(); + /* Initialise filename allocator */ + filename_initialise(); - (void)apple_image_init(); + (void)apple_image_init(); - NSApplication *app = cocoa_prepare_app(); + NSApplication *app = cocoa_prepare_app(); - for (int i = 1; i < argc; i++) { - /* skip -psn_* and other possible options */ - if (argv[i][0] == '-') - continue; + for (int i = 1; i < argc; i++) { + /* skip -psn_* and other possible options */ + if (argv[i][0] == '-') + continue; - error = nsurl_create(argv[i], &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - cocoa_warning(messages_get_errorcode(error), 0); - } + error = nsurl_create(argv[i], &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); } + if (error != NSERROR_OK) { + cocoa_warning(messages_get_errorcode(error), 0); + } + } - [app run]; + [app run]; - netsurf_exit(); + netsurf_exit(); - return 0; + return 0; } diff --git a/frontends/cocoa/PSMTabBarControl/NSBezierPath_AMShading.m b/frontends/cocoa/PSMTabBarControl/NSBezierPath_AMShading.m index 30ee24096..dbd180599 100644 --- a/frontends/cocoa/PSMTabBarControl/NSBezierPath_AMShading.m +++ b/frontends/cocoa/PSMTabBarControl/NSBezierPath_AMShading.m @@ -8,112 +8,119 @@ #import "NSBezierPath_AMShading.h" - @implementation NSBezierPath (AMShading) -static void linearShadedColor(void *info, const CGFloat *in, CGFloat *out){ - CGFloat *colors = (CGFloat *)info; - *out++ = colors[0] + *in * colors[8]; - *out++ = colors[1] + *in * colors[9]; - *out++ = colors[2] + *in * colors[10]; - *out++ = colors[3] + *in * colors[11]; +static void linearShadedColor(void *info, const CGFloat *in, CGFloat *out) +{ + CGFloat *colors = (CGFloat *)info; + *out++ = colors[0] + *in * colors[8]; + *out++ = colors[1] + *in * colors[9]; + *out++ = colors[2] + *in * colors[10]; + *out++ = colors[3] + *in * colors[11]; } -static void bilinearShadedColor(void *info, const CGFloat *in, CGFloat *out){ - CGFloat *colors = (CGFloat *)info; - CGFloat factor = (*in) * 2.0; - if(*in > 0.5) { - factor = 2 - factor; - } - *out++ = colors[0] + factor * colors[8]; - *out++ = colors[1] + factor * colors[9]; - *out++ = colors[2] + factor * colors[10]; - *out++ = colors[3] + factor * colors[11]; +static void bilinearShadedColor(void *info, const CGFloat *in, CGFloat *out) +{ + CGFloat *colors = (CGFloat *)info; + CGFloat factor = (*in) * 2.0; + if (*in > 0.5) { + factor = 2 - factor; + } + *out++ = colors[0] + factor * colors[8]; + *out++ = colors[1] + factor * colors[9]; + *out++ = colors[2] + factor * colors[10]; + *out++ = colors[3] + factor * colors[11]; } -- (void)linearGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor { - static const CGFunctionCallbacks callbacks = {0, &linearShadedColor, NULL}; +- (void)linearGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor +{ + static const CGFunctionCallbacks callbacks = { 0, &linearShadedColor, NULL }; - [self customHorizontalFillWithCallbacks:callbacks firstColor:startColor secondColor:endColor]; + [self customHorizontalFillWithCallbacks:callbacks firstColor:startColor secondColor:endColor]; } -- (void)linearVerticalGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor { - static const CGFunctionCallbacks callbacks = {0, &linearShadedColor, NULL}; +- (void)linearVerticalGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor +{ + static const CGFunctionCallbacks callbacks = { 0, &linearShadedColor, NULL }; - [self customVerticalFillWithCallbacks:callbacks firstColor:startColor secondColor:endColor]; + [self customVerticalFillWithCallbacks:callbacks firstColor:startColor secondColor:endColor]; } -- (void)bilinearGradientFillWithOuterColor:(NSColor *)outerColor innerColor:(NSColor *)innerColor { - static const CGFunctionCallbacks callbacks = {0, &bilinearShadedColor, NULL}; +- (void)bilinearGradientFillWithOuterColor:(NSColor *)outerColor innerColor:(NSColor *)innerColor +{ + static const CGFunctionCallbacks callbacks = { 0, &bilinearShadedColor, NULL }; - [self customHorizontalFillWithCallbacks:callbacks firstColor:innerColor secondColor:outerColor]; + [self customHorizontalFillWithCallbacks:callbacks firstColor:innerColor secondColor:outerColor]; } -- (void)customFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint { - CGColorSpaceRef colorspace; - CGShadingRef shading; - CGFunctionRef function; - CGFloat colors[12]; // pointer to color values - - // get my context - CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - - NSColor *deviceDependentFirstColor = [firstColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - NSColor *deviceDependentSecondColor = [secondColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - - // set up colors for gradient - colors[0] = [deviceDependentFirstColor redComponent]; - colors[1] = [deviceDependentFirstColor greenComponent]; - colors[2] = [deviceDependentFirstColor blueComponent]; - colors[3] = [deviceDependentFirstColor alphaComponent]; - - colors[4] = [deviceDependentSecondColor redComponent]; - colors[5] = [deviceDependentSecondColor greenComponent]; - colors[6] = [deviceDependentSecondColor blueComponent]; - colors[7] = [deviceDependentSecondColor alphaComponent]; - - // difference between start and end color for each color components - colors[8] = (colors[4] - colors[0]); - colors[9] = (colors[5] - colors[1]); - colors[10] = (colors[6] - colors[2]); - colors[11] = (colors[7] - colors[3]); - - // draw gradient - colorspace = CGColorSpaceCreateDeviceRGB(); - size_t components = 1 + CGColorSpaceGetNumberOfComponents(colorspace); - static const CGFloat domain[2] = {0.0, 1.0}; - static const CGFloat range[10] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; - //static const CGFunctionCallbacks callbacks = {0, &bilinearShadedColor, NULL}; - - // Create a CGFunctionRef that describes a function taking 1 input and kChannelsPerColor outputs. - function = CGFunctionCreate(colors, 1, domain, components, range, &functionCallbacks); - - shading = CGShadingCreateAxial(colorspace, startPoint, endPoint, function, NO, NO); - - CGContextSaveGState(currentContext); - [self addClip]; - CGContextDrawShading(currentContext, shading); - CGContextRestoreGState(currentContext); - - CGShadingRelease(shading); - CGFunctionRelease(function); - CGColorSpaceRelease(colorspace); +- (void)customFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint +{ + CGColorSpaceRef colorspace; + CGShadingRef shading; + CGFunctionRef function; + CGFloat colors[12]; // pointer to color values + + // get my context + CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + + NSColor *deviceDependentFirstColor = [firstColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + NSColor *deviceDependentSecondColor = [secondColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + + // set up colors for gradient + colors[0] = [deviceDependentFirstColor redComponent]; + colors[1] = [deviceDependentFirstColor greenComponent]; + colors[2] = [deviceDependentFirstColor blueComponent]; + colors[3] = [deviceDependentFirstColor alphaComponent]; + + colors[4] = [deviceDependentSecondColor redComponent]; + colors[5] = [deviceDependentSecondColor greenComponent]; + colors[6] = [deviceDependentSecondColor blueComponent]; + colors[7] = [deviceDependentSecondColor alphaComponent]; + + // difference between start and end color for each color components + colors[8] = (colors[4] - colors[0]); + colors[9] = (colors[5] - colors[1]); + colors[10] = (colors[6] - colors[2]); + colors[11] = (colors[7] - colors[3]); + + // draw gradient + colorspace = CGColorSpaceCreateDeviceRGB(); + size_t components = 1 + CGColorSpaceGetNumberOfComponents(colorspace); + static const CGFloat domain[2] = { 0.0, 1.0 }; + static const CGFloat range[10] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + //static const CGFunctionCallbacks callbacks = {0, &bilinearShadedColor, NULL}; + + // Create a CGFunctionRef that describes a function taking 1 input and kChannelsPerColor outputs. + function = CGFunctionCreate(colors, 1, domain, components, range, &functionCallbacks); + + shading = CGShadingCreateAxial(colorspace, startPoint, endPoint, function, NO, NO); + + CGContextSaveGState(currentContext); + [self addClip]; + CGContextDrawShading(currentContext, shading); + CGContextRestoreGState(currentContext); + + CGShadingRelease(shading); + CGFunctionRelease(function); + CGColorSpaceRelease(colorspace); } -- (void)customHorizontalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor { - [self customFillWithCallbacks:functionCallbacks - firstColor:firstColor - secondColor:secondColor - startPoint:CGPointMake(0, NSMinY([self bounds])) - endPoint:CGPointMake(0, NSMaxY([self bounds]))]; +- (void)customHorizontalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor +{ + [self customFillWithCallbacks:functionCallbacks + firstColor:firstColor + secondColor:secondColor + startPoint:CGPointMake(0, NSMinY([self bounds])) + endPoint:CGPointMake(0, NSMaxY([self bounds]))]; } -- (void)customVerticalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor { - [self customFillWithCallbacks:functionCallbacks - firstColor:firstColor - secondColor:secondColor - startPoint:CGPointMake(NSMinX([self bounds]), 0) - endPoint:CGPointMake(NSMaxX([self bounds]), 0)]; +- (void)customVerticalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor +{ + [self customFillWithCallbacks:functionCallbacks + firstColor:firstColor + secondColor:secondColor + startPoint:CGPointMake(NSMinX([self bounds]), 0) + endPoint:CGPointMake(NSMaxX([self bounds]), 0)]; } @end diff --git a/frontends/cocoa/PSMTabBarControl/NSString_AITruncation.m b/frontends/cocoa/PSMTabBarControl/NSString_AITruncation.m index a5865cb8a..9d9ce6189 100644 --- a/frontends/cocoa/PSMTabBarControl/NSString_AITruncation.m +++ b/frontends/cocoa/PSMTabBarControl/NSString_AITruncation.m @@ -11,22 +11,24 @@ @implementation NSString (AITruncation) -+ (id)ellipsis { - return [NSString stringWithUTF8String:"\xE2\x80\xA6"]; ++ (id)ellipsis +{ + return [NSString stringWithUTF8String:"\xE2\x80\xA6"]; } -- (NSString *)stringWithEllipsisByTruncatingToLength:(NSUInteger)length { - NSString *returnString; +- (NSString *)stringWithEllipsisByTruncatingToLength:(NSUInteger)length +{ + NSString *returnString; - if(length < [self length]) { - //Truncate and append the ellipsis - returnString = [[self substringToIndex:length - 1] stringByAppendingString:[NSString ellipsis]]; - } else { - //We don't need to truncate, so don't append an ellipsis - returnString = [self copy]; - } + if (length < [self length]) { + //Truncate and append the ellipsis + returnString = [[self substringToIndex:length - 1] stringByAppendingString:[NSString ellipsis]]; + } else { + //We don't need to truncate, so don't append an ellipsis + returnString = [self copy]; + } - return returnString; + return returnString; } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMOverflowPopUpButton.m b/frontends/cocoa/PSMTabBarControl/PSMOverflowPopUpButton.m index 8b71b7703..d589227c5 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMOverflowPopUpButton.m +++ b/frontends/cocoa/PSMTabBarControl/PSMOverflowPopUpButton.m @@ -15,134 +15,143 @@ @implementation PSMOverflowPopUpButton -- (id)initWithFrame:(NSRect)frameRect pullsDown:(BOOL)flag { - if ((self = [super initWithFrame:frameRect pullsDown:YES]) != nil) { - [self setBezelStyle:NSRegularSquareBezelStyle]; - [self setBordered:NO]; - [self setTitle:@""]; - [self setPreferredEdge:NSMaxXEdge]; - _PSMTabBarOverflowPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImage"]]; - _PSMTabBarOverflowDownPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImagePressed"]]; - _animatingAlternateImage = NO; - } - return self; +- (id)initWithFrame:(NSRect)frameRect pullsDown:(BOOL)flag +{ + if ((self = [super initWithFrame:frameRect pullsDown:YES]) != nil) { + [self setBezelStyle:NSRegularSquareBezelStyle]; + [self setBordered:NO]; + [self setTitle:@""]; + [self setPreferredEdge:NSMaxXEdge]; + _PSMTabBarOverflowPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImage"]]; + _PSMTabBarOverflowDownPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImagePressed"]]; + _animatingAlternateImage = NO; + } + return self; } -- (void)drawRect:(NSRect)rect { - if(_PSMTabBarOverflowPopUpImage == nil) { - [super drawRect:rect]; - return; - } +- (void)drawRect:(NSRect)rect +{ + if (_PSMTabBarOverflowPopUpImage == nil) { + [super drawRect:rect]; + return; + } - NSImage *image = (_down) ? _PSMTabBarOverflowDownPopUpImage : _PSMTabBarOverflowPopUpImage; - NSSize imageSize = [image size]; - NSRect bounds = [self bounds]; + NSImage *image = (_down) ? _PSMTabBarOverflowDownPopUpImage : _PSMTabBarOverflowPopUpImage; + NSSize imageSize = [image size]; + NSRect bounds = [self bounds]; - NSPoint drawPoint = NSMakePoint(NSMidX(bounds) - (imageSize.width * 0.5f), NSMidY(bounds) - (imageSize.height * 0.5f)); + NSPoint drawPoint = NSMakePoint(NSMidX(bounds) - (imageSize.width * 0.5f), NSMidY(bounds) - (imageSize.height * 0.5f)); - if([self isFlipped]) { - drawPoint.y += imageSize.height; - } + if ([self isFlipped]) { + drawPoint.y += imageSize.height; + } - [image drawAtPoint:drawPoint fromRect: CGRectZero operation:NSCompositingOperationSourceOver fraction:(_animatingAlternateImage ? 0.7f : 1.0f)]; + [image drawAtPoint:drawPoint fromRect:CGRectZero operation:NSCompositingOperationSourceOver fraction:(_animatingAlternateImage ? 0.7f : 1.0f)]; - if(_animatingAlternateImage) { - NSImage *alternateImage = [self alternateImage]; - NSSize altImageSize = [alternateImage size]; - drawPoint = NSMakePoint(NSMidX(bounds) - (altImageSize.width * 0.5f), NSMidY(bounds) - (altImageSize.height * 0.5f)); + if (_animatingAlternateImage) { + NSImage *alternateImage = [self alternateImage]; + NSSize altImageSize = [alternateImage size]; + drawPoint = NSMakePoint(NSMidX(bounds) - (altImageSize.width * 0.5f), NSMidY(bounds) - (altImageSize.height * 0.5f)); - if([self isFlipped]) { - drawPoint.y += altImageSize.height; - } + if ([self isFlipped]) { + drawPoint.y += altImageSize.height; + } - [[self alternateImage] drawAtPoint:drawPoint fromRect: CGRectZero operation:NSCompositingOperationSourceOver fraction:sin(_animationValue * M_PI)]; - } + [[self alternateImage] drawAtPoint:drawPoint fromRect:CGRectZero operation:NSCompositingOperationSourceOver fraction:sin(_animationValue * M_PI)]; + } } -- (void)mouseDown:(NSEvent *)event { - _down = YES; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:NSMenuDidEndTrackingNotification object:[self menu]]; - [self setNeedsDisplay:YES]; - [super mouseDown:event]; +- (void)mouseDown:(NSEvent *)event +{ + _down = YES; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:NSMenuDidEndTrackingNotification object:[self menu]]; + [self setNeedsDisplay:YES]; + [super mouseDown:event]; } -- (void)setHidden:(BOOL)value { - if([self isHidden] != value) { - if(value) { - // Stop any animating alternate image if we hide - [_animationTimer invalidate], _animationTimer = nil; - } else if(_animatingAlternateImage) { - // Restart any animating alternate image if we unhide - _animationValue = ANIMATION_STEP; - _animationTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(animateStep:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; - } - } - - [super setHidden:value]; +- (void)setHidden:(BOOL)value +{ + if ([self isHidden] != value) { + if (value) { + // Stop any animating alternate image if we hide + [_animationTimer invalidate], _animationTimer = nil; + } else if (_animatingAlternateImage) { + // Restart any animating alternate image if we unhide + _animationValue = ANIMATION_STEP; + _animationTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(animateStep:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; + } + } + + [super setHidden:value]; } -- (void)notificationReceived:(NSNotification *)notification { - _down = NO; - [self setNeedsDisplay:YES]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; +- (void)notificationReceived:(NSNotification *)notification +{ + _down = NO; + [self setNeedsDisplay:YES]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)setAnimatingAlternateImage:(BOOL)flag { - if(_animatingAlternateImage != flag) { - _animatingAlternateImage = flag; - - if(![self isHidden]) { - if(flag) { - _animationValue = ANIMATION_STEP; - _animationTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(animateStep:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; - } else { - [_animationTimer invalidate], _animationTimer = nil; - } - - [self setNeedsDisplay:YES]; - } - } +- (void)setAnimatingAlternateImage:(BOOL)flag +{ + if (_animatingAlternateImage != flag) { + _animatingAlternateImage = flag; + + if (![self isHidden]) { + if (flag) { + _animationValue = ANIMATION_STEP; + _animationTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(animateStep:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; + } else { + [_animationTimer invalidate], _animationTimer = nil; + } + + [self setNeedsDisplay:YES]; + } + } } - (BOOL)animatingAlternateImage { - return _animatingAlternateImage; + return _animatingAlternateImage; } -- (void)animateStep:(NSTimer *)timer { - _animationValue += ANIMATION_STEP; +- (void)animateStep:(NSTimer *)timer +{ + _animationValue += ANIMATION_STEP; - if(_animationValue >= 1) { - _animationValue = ANIMATION_STEP; - } + if (_animationValue >= 1) { + _animationValue = ANIMATION_STEP; + } - [self setNeedsDisplay:YES]; + [self setNeedsDisplay:YES]; } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - [super encodeWithCoder:aCoder]; - if([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_PSMTabBarOverflowPopUpImage forKey:@"PSMTabBarOverflowPopUpImage"]; - [aCoder encodeObject:_PSMTabBarOverflowDownPopUpImage forKey:@"PSMTabBarOverflowDownPopUpImage"]; - [aCoder encodeBool:_animatingAlternateImage forKey:@"PSMTabBarOverflowAnimatingAlternateImage"]; - } +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_PSMTabBarOverflowPopUpImage forKey:@"PSMTabBarOverflowPopUpImage"]; + [aCoder encodeObject:_PSMTabBarOverflowDownPopUpImage forKey:@"PSMTabBarOverflowDownPopUpImage"]; + [aCoder encodeBool:_animatingAlternateImage forKey:@"PSMTabBarOverflowAnimatingAlternateImage"]; + } } -- (id)initWithCoder:(NSCoder *)aDecoder { - if((self = [super initWithCoder:aDecoder])) { - if([aDecoder allowsKeyedCoding]) { - _PSMTabBarOverflowPopUpImage = - [aDecoder decodeObjectForKey:@"PSMTabBarOverflowPopUpImage"]; - _PSMTabBarOverflowDownPopUpImage = [aDecoder decodeObjectForKey:@"PSMTabBarOverflowDownPopUpImage"]; - [self setAnimatingAlternateImage:[aDecoder decodeBoolForKey:@"PSMTabBarOverflowAnimatingAlternateImage"]]; - } - } - return self; +- (id)initWithCoder:(NSCoder *)aDecoder +{ + if ((self = [super initWithCoder:aDecoder])) { + if ([aDecoder allowsKeyedCoding]) { + _PSMTabBarOverflowPopUpImage = + [aDecoder decodeObjectForKey:@"PSMTabBarOverflowPopUpImage"]; + _PSMTabBarOverflowDownPopUpImage = [aDecoder decodeObjectForKey:@"PSMTabBarOverflowDownPopUpImage"]; + [self setAnimatingAlternateImage:[aDecoder decodeBoolForKey:@"PSMTabBarOverflowAnimatingAlternateImage"]]; + } + } + return self; } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMProgressIndicator.m b/frontends/cocoa/PSMTabBarControl/PSMProgressIndicator.m index afc727d7a..4532f31be 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMProgressIndicator.m +++ b/frontends/cocoa/PSMTabBarControl/PSMProgressIndicator.m @@ -17,24 +17,27 @@ @implementation PSMProgressIndicator -- (id) initWithFrame: (NSRect)frameRect +- (id)initWithFrame:(NSRect)frameRect { - if ((self = [super initWithFrame: frameRect]) == nil) return nil; - [self setControlSize: NSControlSizeSmall]; - return self; + if ((self = [super initWithFrame:frameRect]) == nil) + return nil; + [self setControlSize:NSControlSizeSmall]; + return self; } // overrides to make tab bar control re-layout things if status changes -- (void)setHidden:(BOOL)flag { - [super setHidden:flag]; - [(PSMTabBarControl *)[self superview] update]; +- (void)setHidden:(BOOL)flag +{ + [super setHidden:flag]; + [(PSMTabBarControl *)[self superview] update]; } -- (void)stopAnimation:(id)sender { - [NSObject cancelPreviousPerformRequestsWithTarget:self - selector:@selector(startAnimation:) - object:nil]; - [super stopAnimation:sender]; +- (void)stopAnimation:(id)sender +{ + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(startAnimation:) + object:nil]; + [super stopAnimation:sender]; } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMRolloverButton.m b/frontends/cocoa/PSMTabBarControl/PSMRolloverButton.m index 1da82c0db..65df6aa0f 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMRolloverButton.m +++ b/frontends/cocoa/PSMTabBarControl/PSMRolloverButton.m @@ -10,154 +10,171 @@ @implementation PSMRolloverButton -- (void)awakeFromNib { - if([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]) { - [super awakeFromNib]; - } +- (void)awakeFromNib +{ + if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]) { + [super awakeFromNib]; + } - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(rolloverFrameDidChange:) - name:NSViewFrameDidChangeNotification - object:self]; - [self setPostsFrameChangedNotifications:YES]; - [self resetCursorRects]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(rolloverFrameDidChange:) + name:NSViewFrameDidChangeNotification + object:self]; + [self setPostsFrameChangedNotifications:YES]; + [self resetCursorRects]; - _myTrackingRectTag = -1; + _myTrackingRectTag = -1; } -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self removeTrackingRect]; + [self removeTrackingRect]; } // the regular image -- (void)setUsualImage:(NSImage *)newImage { - _usualImage = newImage; +- (void)setUsualImage:(NSImage *)newImage +{ + _usualImage = newImage; - [self setImage:_usualImage]; + [self setImage:_usualImage]; } -- (NSImage *)usualImage { - return _usualImage; +- (NSImage *)usualImage +{ + return _usualImage; } -- (void)setRolloverImage:(NSImage *)newImage { - _rolloverImage = newImage; +- (void)setRolloverImage:(NSImage *)newImage +{ + _rolloverImage = newImage; } -- (NSImage *)rolloverImage { - return _rolloverImage; +- (NSImage *)rolloverImage +{ + return _rolloverImage; } //Remove old tracking rects when we change superviews -- (void)viewWillMoveToSuperview:(NSView *)newSuperview { - [self removeTrackingRect]; +- (void)viewWillMoveToSuperview:(NSView *)newSuperview +{ + [self removeTrackingRect]; - [super viewWillMoveToSuperview:newSuperview]; + [super viewWillMoveToSuperview:newSuperview]; } -- (void)viewDidMoveToSuperview { - [super viewDidMoveToSuperview]; +- (void)viewDidMoveToSuperview +{ + [super viewDidMoveToSuperview]; - [self resetCursorRects]; + [self resetCursorRects]; } -- (void)viewWillMoveToWindow:(NSWindow *)newWindow { - [self removeTrackingRect]; +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + [self removeTrackingRect]; - [super viewWillMoveToWindow:newWindow]; + [super viewWillMoveToWindow:newWindow]; } -- (void)viewDidMoveToWindow { - [super viewDidMoveToWindow]; - - [self resetCursorRects]; -} +- (void)viewDidMoveToWindow +{ + [super viewDidMoveToWindow]; -- (void)rolloverFrameDidChange:(NSNotification *)inNotification { - [self resetCursorRects]; + [self resetCursorRects]; } -- (void)addTrackingRect { - // assign a tracking rect to watch for mouse enter/exit - NSRect trackRect = [self bounds]; - NSPoint localPoint = [self convertPoint: NSPointFromCGPoint([self.window convertRectFromScreen: (NSRect){.origin = NSEvent.mouseLocation, .size = CGSizeMake(1, 1)}].origin) fromView: nil]; - BOOL mouseInside = NSPointInRect(localPoint, trackRect); - - _myTrackingRectTag = [self addTrackingRect:trackRect owner:self userData:nil assumeInside:mouseInside]; - if(mouseInside) { - //[self mouseEntered:nil]; - [self setImage:_rolloverImage]; - } else{ - //[self mouseExited:nil]; - [self setImage:_usualImage]; - } +- (void)rolloverFrameDidChange:(NSNotification *)inNotification +{ + [self resetCursorRects]; } -- (void)removeTrackingRect { - if(_myTrackingRectTag != -1) { - [self removeTrackingRect:_myTrackingRectTag]; - } - _myTrackingRectTag = -1; +- (void)addTrackingRect +{ + // assign a tracking rect to watch for mouse enter/exit + NSRect trackRect = [self bounds]; + NSPoint localPoint = [self convertPoint:NSPointFromCGPoint([self.window convertRectFromScreen:(NSRect){.origin = NSEvent.mouseLocation, .size = CGSizeMake(1, 1) }].origin) fromView:nil]; + BOOL mouseInside = NSPointInRect(localPoint, trackRect); + + _myTrackingRectTag = [self addTrackingRect:trackRect owner:self userData:nil assumeInside:mouseInside]; + if (mouseInside) { + //[self mouseEntered:nil]; + [self setImage:_rolloverImage]; + } else { + //[self mouseExited:nil]; + [self setImage:_usualImage]; + } +} + +- (void)removeTrackingRect +{ + if (_myTrackingRectTag != -1) { + [self removeTrackingRect:_myTrackingRectTag]; + } + _myTrackingRectTag = -1; } // override for rollover effect - (void)mouseEntered:(NSEvent *)theEvent { - // set rollover image - [self setImage:_rolloverImage]; + // set rollover image + [self setImage:_rolloverImage]; - [super mouseEntered:theEvent]; + [super mouseEntered:theEvent]; } - (void)mouseExited:(NSEvent *)theEvent { - // restore usual image - [self setImage:_usualImage]; + // restore usual image + [self setImage:_usualImage]; - [super mouseExited:theEvent]; + [super mouseExited:theEvent]; } -- (void)resetCursorRects { - // called when the button rect has been changed - [self removeTrackingRect]; - [self addTrackingRect]; +- (void)resetCursorRects +{ + // called when the button rect has been changed + [self removeTrackingRect]; + [self addTrackingRect]; } -- (void)setFrame:(NSRect)rect { - [super setFrame:rect]; - [self resetCursorRects]; +- (void)setFrame:(NSRect)rect +{ + [super setFrame:rect]; + [self resetCursorRects]; } -- (void)setBounds:(NSRect)rect { - [super setBounds:rect]; - [self resetCursorRects]; +- (void)setBounds:(NSRect)rect +{ + [super setBounds:rect]; + [self resetCursorRects]; } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - [super encodeWithCoder:aCoder]; - if([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_rolloverImage forKey:@"rolloverImage"]; - [aCoder encodeObject:_usualImage forKey:@"usualImage"]; - [aCoder encodeInt64:_myTrackingRectTag forKey:@"myTrackingRectTag"]; - } +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_rolloverImage forKey:@"rolloverImage"]; + [aCoder encodeObject:_usualImage forKey:@"usualImage"]; + [aCoder encodeInt64:_myTrackingRectTag forKey:@"myTrackingRectTag"]; + } } -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self) { - if([aDecoder allowsKeyedCoding]) { - _rolloverImage = [aDecoder decodeObjectForKey:@"rolloverImage"] ; - _usualImage = [aDecoder decodeObjectForKey:@"usualImage"] ; - _myTrackingRectTag = [aDecoder decodeInt64ForKey:@"myTrackingRectTag"]; - } - } - return self; +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _rolloverImage = [aDecoder decodeObjectForKey:@"rolloverImage"]; + _usualImage = [aDecoder decodeObjectForKey:@"usualImage"]; + _myTrackingRectTag = [aDecoder decodeInt64ForKey:@"myTrackingRectTag"]; + } + } + return self; } - @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabBarCell.m b/frontends/cocoa/PSMTabBarControl/PSMTabBarCell.m index 0f21fe5c3..5a8edfd77 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabBarCell.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabBarCell.m @@ -17,465 +17,520 @@ #pragma mark - #pragma mark Creation/Destruction -- (id)initWithControlView:(PSMTabBarControl *)controlView { - if((self = [super init])) { - _controlView = controlView; - _closeButtonTrackingTag = 0; - _cellTrackingTag = 0; - _closeButtonOver = NO; - _closeButtonPressed = NO; - _indicator = [[PSMProgressIndicator alloc] initWithFrame:NSMakeRect(0.0, 0.0, kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth)]; - [_indicator setStyle:NSProgressIndicatorSpinningStyle]; - [_indicator setAutoresizingMask:NSViewMinYMargin]; - _hasCloseButton = YES; - _isCloseButtonSuppressed = NO; - _count = 0; - _countColor = nil; - _isEdited = NO; - _isPlaceholder = NO; - } - return self; -} - -- (id)initPlaceholderWithFrame:(NSRect)frame expanded:(BOOL)value inControlView:(PSMTabBarControl *)controlView { - if((self = [super init])) { - _controlView = controlView; - _isPlaceholder = YES; - if(!value) { - if([controlView orientation] == PSMTabBarHorizontalOrientation) { - frame.size.width = 0.0; - } else { - frame.size.height = 0.0; - } - } - [self setFrame:frame]; - _closeButtonTrackingTag = 0; - _cellTrackingTag = 0; - _closeButtonOver = NO; - _closeButtonPressed = NO; - _indicator = nil; - _hasCloseButton = YES; - _isCloseButtonSuppressed = NO; - _count = 0; - _countColor = nil; - _isEdited = NO; - - if(value) { - [self setCurrentStep:(kPSMTabDragAnimationSteps - 1)]; - } else { - [self setCurrentStep:0]; - } - } - return self; -} - -- (void)dealloc { - - [_indicator removeFromSuperviewWithoutNeedingDisplay]; +- (id)initWithControlView:(PSMTabBarControl *)controlView +{ + if ((self = [super init])) { + _controlView = controlView; + _closeButtonTrackingTag = 0; + _cellTrackingTag = 0; + _closeButtonOver = NO; + _closeButtonPressed = NO; + _indicator = [[PSMProgressIndicator alloc] initWithFrame:NSMakeRect(0.0, 0.0, kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth)]; + [_indicator setStyle:NSProgressIndicatorSpinningStyle]; + [_indicator setAutoresizingMask:NSViewMinYMargin]; + _hasCloseButton = YES; + _isCloseButtonSuppressed = NO; + _count = 0; + _countColor = nil; + _isEdited = NO; + _isPlaceholder = NO; + } + return self; +} + +- (id)initPlaceholderWithFrame:(NSRect)frame expanded:(BOOL)value inControlView:(PSMTabBarControl *)controlView +{ + if ((self = [super init])) { + _controlView = controlView; + _isPlaceholder = YES; + if (!value) { + if ([controlView orientation] == PSMTabBarHorizontalOrientation) { + frame.size.width = 0.0; + } else { + frame.size.height = 0.0; + } + } + [self setFrame:frame]; + _closeButtonTrackingTag = 0; + _cellTrackingTag = 0; + _closeButtonOver = NO; + _closeButtonPressed = NO; + _indicator = nil; + _hasCloseButton = YES; + _isCloseButtonSuppressed = NO; + _count = 0; + _countColor = nil; + _isEdited = NO; + + if (value) { + [self setCurrentStep:(kPSMTabDragAnimationSteps - 1)]; + } else { + [self setCurrentStep:0]; + } + } + return self; +} + +- (void)dealloc +{ + [_indicator removeFromSuperviewWithoutNeedingDisplay]; } #pragma mark - #pragma mark Accessors -- (id)controlView { - return _controlView; +- (id)controlView +{ + return _controlView; } -- (void)setControlView:(id)view { - // no retain release pattern, as this simply switches a tab to another view. - _controlView = view; +- (void)setControlView:(id)view +{ + // no retain release pattern, as this simply switches a tab to another view. + _controlView = view; } -- (NSTrackingRectTag)closeButtonTrackingTag { - return _closeButtonTrackingTag; +- (NSTrackingRectTag)closeButtonTrackingTag +{ + return _closeButtonTrackingTag; } -- (void)setCloseButtonTrackingTag:(NSTrackingRectTag)tag { - _closeButtonTrackingTag = tag; +- (void)setCloseButtonTrackingTag:(NSTrackingRectTag)tag +{ + _closeButtonTrackingTag = tag; } -- (NSTrackingRectTag)cellTrackingTag { - return _cellTrackingTag; +- (NSTrackingRectTag)cellTrackingTag +{ + return _cellTrackingTag; } -- (void)setCellTrackingTag:(NSTrackingRectTag)tag { - _cellTrackingTag = tag; +- (void)setCellTrackingTag:(NSTrackingRectTag)tag +{ + _cellTrackingTag = tag; } -- (CGFloat)width { - return _frame.size.width; +- (CGFloat)width +{ + return _frame.size.width; } -- (NSRect)frame { - return _frame; +- (NSRect)frame +{ + return _frame; } -- (void)setFrame:(NSRect)rect { - _frame = rect; +- (void)setFrame:(NSRect)rect +{ + _frame = rect; - //move the status indicator along with the rest of the cell - if(![[self indicator] isHidden] && ![_controlView isTabBarHidden]) { - [[self indicator] setFrame:[self indicatorRectForFrame:rect]]; - } + //move the status indicator along with the rest of the cell + if (![[self indicator] isHidden] && ![_controlView isTabBarHidden]) { + [[self indicator] setFrame:[self indicatorRectForFrame:rect]]; + } } -- (void)setStringValue:(NSString *)aString { - [super setStringValue:aString]; - _stringSize = [[self attributedStringValue] size]; - // need to redisplay now - binding observation was too quick. - [_controlView update]; +- (void)setStringValue:(NSString *)aString +{ + [super setStringValue:aString]; + _stringSize = [[self attributedStringValue] size]; + // need to redisplay now - binding observation was too quick. + [_controlView update]; } -- (NSSize)stringSize { - return _stringSize; +- (NSSize)stringSize +{ + return _stringSize; } -- (NSAttributedString *)attributedStringValue { - return [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] attributedStringValueForTabCell:self]; +- (NSAttributedString *)attributedStringValue +{ + return [(id)[(PSMTabBarControl *)_controlView style] attributedStringValueForTabCell:self]; } -- (NSInteger)tabState { - return _tabState; +- (NSInteger)tabState +{ + return _tabState; } -- (void)setTabState:(NSInteger)state { - _tabState = state; +- (void)setTabState:(NSInteger)state +{ + _tabState = state; } -- (NSProgressIndicator *)indicator { - return _indicator; +- (NSProgressIndicator *)indicator +{ + return _indicator; } -- (BOOL)isInOverflowMenu { - return _isInOverflowMenu; +- (BOOL)isInOverflowMenu +{ + return _isInOverflowMenu; } -- (void)setIsInOverflowMenu:(BOOL)value { - if(_isInOverflowMenu != value) { - _isInOverflowMenu = value; - if([[[self controlView] delegate] respondsToSelector:@selector(tabView:tabViewItem:isInOverflowMenu:)]) { - [[[self controlView] delegate] tabView:[self controlView] tabViewItem:[self representedObject] isInOverflowMenu:_isInOverflowMenu]; - } - } +- (void)setIsInOverflowMenu:(BOOL)value +{ + if (_isInOverflowMenu != value) { + _isInOverflowMenu = value; + if ([[[self controlView] delegate] respondsToSelector:@selector(tabView:tabViewItem:isInOverflowMenu:)]) { + [[[self controlView] delegate] tabView:[self controlView] tabViewItem:[self representedObject] isInOverflowMenu:_isInOverflowMenu]; + } + } } -- (BOOL)closeButtonPressed { - return _closeButtonPressed; +- (BOOL)closeButtonPressed +{ + return _closeButtonPressed; } -- (void)setCloseButtonPressed:(BOOL)value { - _closeButtonPressed = value; +- (void)setCloseButtonPressed:(BOOL)value +{ + _closeButtonPressed = value; } -- (BOOL)closeButtonOver { - return(_closeButtonOver && ([_controlView allowsBackgroundTabClosing] || ([self tabState] & PSMTab_SelectedMask) || [[NSApp currentEvent] modifierFlags] & NSEventModifierFlagCommand)); +- (BOOL)closeButtonOver +{ + return (_closeButtonOver && ([_controlView allowsBackgroundTabClosing] || ([self tabState] & PSMTab_SelectedMask) || [[NSApp currentEvent] modifierFlags] & NSEventModifierFlagCommand)); } -- (void)setCloseButtonOver:(BOOL)value { - _closeButtonOver = value; +- (void)setCloseButtonOver:(BOOL)value +{ + _closeButtonOver = value; } -- (BOOL)hasCloseButton { - return _hasCloseButton; +- (BOOL)hasCloseButton +{ + return _hasCloseButton; } - (void)setHasCloseButton:(BOOL)set { - _hasCloseButton = set; + _hasCloseButton = set; } - (void)setCloseButtonSuppressed:(BOOL)suppress { - _isCloseButtonSuppressed = suppress; + _isCloseButtonSuppressed = suppress; } - (BOOL)isCloseButtonSuppressed { - return _isCloseButtonSuppressed; + return _isCloseButtonSuppressed; } -- (BOOL)hasIcon { - return _hasIcon; +- (BOOL)hasIcon +{ + return _hasIcon; } -- (void)setHasIcon:(BOOL)value { - _hasIcon = value; - //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast +- (void)setHasIcon:(BOOL)value +{ + _hasIcon = value; + //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast } -- (BOOL)hasLargeImage { - return _hasLargeImage; +- (BOOL)hasLargeImage +{ + return _hasLargeImage; } -- (void)setHasLargeImage:(BOOL)value { - _hasLargeImage = value; +- (void)setHasLargeImage:(BOOL)value +{ + _hasLargeImage = value; } - -- (NSInteger)count { - return _count; +- (NSInteger)count +{ + return _count; } -- (void)setCount:(NSInteger)value { - _count = value; - //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast +- (void)setCount:(NSInteger)value +{ + _count = value; + //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast } -- (NSColor *)countColor { - return _countColor; +- (NSColor *)countColor +{ + return _countColor; } -- (void)setCountColor:(NSColor *)color { - _countColor = color; +- (void)setCountColor:(NSColor *)color +{ + _countColor = color; } -- (BOOL)isPlaceholder { - return _isPlaceholder; +- (BOOL)isPlaceholder +{ + return _isPlaceholder; } - (void)setIsPlaceholder:(BOOL)value { - _isPlaceholder = value; + _isPlaceholder = value; } -- (NSInteger)currentStep { - return _currentStep; +- (NSInteger)currentStep +{ + return _currentStep; } -- (void)setCurrentStep:(NSInteger)value { - if(value < 0) { - value = 0; - } +- (void)setCurrentStep:(NSInteger)value +{ + if (value < 0) { + value = 0; + } - if(value > (kPSMTabDragAnimationSteps - 1)) { - value = (kPSMTabDragAnimationSteps - 1); - } + if (value > (kPSMTabDragAnimationSteps - 1)) { + value = (kPSMTabDragAnimationSteps - 1); + } - _currentStep = value; + _currentStep = value; } -- (BOOL)isEdited { - return _isEdited; +- (BOOL)isEdited +{ + return _isEdited; } -- (void)setIsEdited:(BOOL)value { - _isEdited = value; - //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast +- (void)setIsEdited:(BOOL)value +{ + _isEdited = value; + //[_controlView update:[[self controlView] automaticallyAnimates]]; // binding notice is too fast } #pragma mark - #pragma mark Bindings -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - // the progress indicator, label, icon, or count has changed - redraw the control view - //[_controlView update]; - //I seem to have run into some odd issue with update not being called at the right time. This seems to avoid the problem. - [_controlView performSelector:@selector(update) withObject:nil afterDelay:0.0]; +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // the progress indicator, label, icon, or count has changed - redraw the control view + //[_controlView update]; + //I seem to have run into some odd issue with update not being called at the right time. This seems to avoid the problem. + [_controlView performSelector:@selector(update) withObject:nil afterDelay:0.0]; } #pragma mark - #pragma mark Component Attributes -- (NSRect)indicatorRectForFrame:(NSRect)cellFrame { - return [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] indicatorRectForTabCell:self]; +- (NSRect)indicatorRectForFrame:(NSRect)cellFrame +{ + return [(id)[(PSMTabBarControl *)_controlView style] indicatorRectForTabCell:self]; } -- (NSRect)closeButtonRectForFrame:(NSRect)cellFrame { - return [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] closeButtonRectForTabCell:self withFrame:cellFrame]; +- (NSRect)closeButtonRectForFrame:(NSRect)cellFrame +{ + return [(id)[(PSMTabBarControl *)_controlView style] closeButtonRectForTabCell:self withFrame:cellFrame]; } -- (CGFloat)minimumWidthOfCell { - return [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] minimumWidthOfTabCell:self]; +- (CGFloat)minimumWidthOfCell +{ + return [(id)[(PSMTabBarControl *)_controlView style] minimumWidthOfTabCell:self]; } -- (CGFloat)desiredWidthOfCell { - return [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] desiredWidthOfTabCell:self]; +- (CGFloat)desiredWidthOfCell +{ + return [(id)[(PSMTabBarControl *)_controlView style] desiredWidthOfTabCell:self]; } #pragma mark - #pragma mark Drawing -- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - if(_isPlaceholder) { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; - NSRectFillUsingOperation(cellFrame, NSCompositingOperationSourceAtop); - return; - } +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if (_isPlaceholder) { + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; + NSRectFillUsingOperation(cellFrame, NSCompositingOperationSourceAtop); + return; + } - [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] drawTabCell:self]; + [(id)[(PSMTabBarControl *)_controlView style] drawTabCell:self]; } #pragma mark - #pragma mark Tracking -- (void)mouseEntered:(NSEvent *)theEvent { - // check for which tag - if([theEvent trackingNumber] == _closeButtonTrackingTag) { - _closeButtonOver = YES; - } - if([theEvent trackingNumber] == _cellTrackingTag) { - [self setHighlighted:YES]; - [_controlView setNeedsDisplay:NO]; - } +- (void)mouseEntered:(NSEvent *)theEvent +{ + // check for which tag + if ([theEvent trackingNumber] == _closeButtonTrackingTag) { + _closeButtonOver = YES; + } + if ([theEvent trackingNumber] == _cellTrackingTag) { + [self setHighlighted:YES]; + [_controlView setNeedsDisplay:NO]; + } - // scrubtastic - if([_controlView allowsScrubbing] && ([theEvent modifierFlags] & NSEventModifierFlagOption)) { - [_controlView performSelector:@selector(tabClick:) withObject:self]; - } + // scrubtastic + if ([_controlView allowsScrubbing] && ([theEvent modifierFlags] & NSEventModifierFlagOption)) { + [_controlView performSelector:@selector(tabClick:) withObject:self]; + } - // tell the control we only need to redraw the affected tab - [_controlView setNeedsDisplayInRect:NSInsetRect([self frame], -2, -2)]; + // tell the control we only need to redraw the affected tab + [_controlView setNeedsDisplayInRect:NSInsetRect([self frame], -2, -2)]; } -- (void)mouseExited:(NSEvent *)theEvent { - // check for which tag - if([theEvent trackingNumber] == _closeButtonTrackingTag) { - _closeButtonOver = NO; - } +- (void)mouseExited:(NSEvent *)theEvent +{ + // check for which tag + if ([theEvent trackingNumber] == _closeButtonTrackingTag) { + _closeButtonOver = NO; + } - if([theEvent trackingNumber] == _cellTrackingTag) { - [self setHighlighted:NO]; - [_controlView setNeedsDisplay:NO]; - } + if ([theEvent trackingNumber] == _cellTrackingTag) { + [self setHighlighted:NO]; + [_controlView setNeedsDisplay:NO]; + } - //tell the control we only need to redraw the affected tab - [_controlView setNeedsDisplayInRect:NSInsetRect([self frame], -2, -2)]; + //tell the control we only need to redraw the affected tab + [_controlView setNeedsDisplayInRect:NSInsetRect([self frame], -2, -2)]; } #pragma mark - #pragma mark Drag Support -- (NSImage *)dragImage { - NSRect cellFrame = [(id < PSMTabStyle >)[(PSMTabBarControl *)_controlView style] dragRectForTabCell:self orientation:(PSMTabBarOrientation)[(PSMTabBarControl *)_controlView orientation]]; - //NSRect cellFrame = [self frame]; - - [_controlView lockFocus]; - NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:cellFrame] ; - [_controlView unlockFocus]; - NSImage *image = [[NSImage alloc] initWithSize:[rep size]]; - [image addRepresentation:rep]; - NSImage *returnImage = [[NSImage alloc] initWithSize:[rep size]]; - [returnImage lockFocus]; - [image drawAtPoint:NSMakePoint(0.0, 0.0) fromRect: NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - [returnImage unlockFocus]; - if(![[self indicator] isHidden]) { - NSImage *pi = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"pi"]]; - [returnImage lockFocus]; - NSPoint indicatorPoint = NSMakePoint([self frame].size.width - MARGIN_X - kPSMTabBarIndicatorWidth, MARGIN_Y); - [pi drawAtPoint:indicatorPoint fromRect: NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - [returnImage unlockFocus]; - } - return returnImage; +- (NSImage *)dragImage +{ + NSRect cellFrame = [(id)[(PSMTabBarControl *)_controlView style] dragRectForTabCell:self orientation:(PSMTabBarOrientation)[(PSMTabBarControl *)_controlView orientation]]; + //NSRect cellFrame = [self frame]; + + [_controlView lockFocus]; + NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:cellFrame]; + [_controlView unlockFocus]; + NSImage *image = [[NSImage alloc] initWithSize:[rep size]]; + [image addRepresentation:rep]; + NSImage *returnImage = [[NSImage alloc] initWithSize:[rep size]]; + [returnImage lockFocus]; + [image drawAtPoint:NSMakePoint(0.0, 0.0) fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + [returnImage unlockFocus]; + if (![[self indicator] isHidden]) { + NSImage *pi = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"pi"]]; + [returnImage lockFocus]; + NSPoint indicatorPoint = NSMakePoint([self frame].size.width - MARGIN_X - kPSMTabBarIndicatorWidth, MARGIN_Y); + [pi drawAtPoint:indicatorPoint fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + [returnImage unlockFocus]; + } + return returnImage; } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - [super encodeWithCoder:aCoder]; - if([aCoder allowsKeyedCoding]) { - [aCoder encodeRect:_frame forKey:@"frame"]; - [aCoder encodeSize:_stringSize forKey:@"stringSize"]; - [aCoder encodeInteger:_currentStep forKey:@"currentStep"]; - [aCoder encodeBool:_isPlaceholder forKey:@"isPlaceholder"]; - [aCoder encodeInteger:_tabState forKey:@"tabState"]; - [aCoder encodeInteger:_closeButtonTrackingTag forKey:@"closeButtonTrackingTag"]; - [aCoder encodeInteger:_cellTrackingTag forKey:@"cellTrackingTag"]; - [aCoder encodeBool:_closeButtonOver forKey:@"closeButtonOver"]; - [aCoder encodeBool:_closeButtonPressed forKey:@"closeButtonPressed"]; - [aCoder encodeObject:_indicator forKey:@"indicator"]; - [aCoder encodeBool:_isInOverflowMenu forKey:@"isInOverflowMenu"]; - [aCoder encodeBool:_hasCloseButton forKey:@"hasCloseButton"]; - [aCoder encodeBool:_isCloseButtonSuppressed forKey:@"isCloseButtonSuppressed"]; - [aCoder encodeBool:_hasIcon forKey:@"hasIcon"]; - [aCoder encodeBool:_hasLargeImage forKey:@"hasLargeImage"]; - [aCoder encodeInteger:_count forKey:@"count"]; - [aCoder encodeBool:_isEdited forKey:@"isEdited"]; - } -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self) { - if([aDecoder allowsKeyedCoding]) { - _frame = [aDecoder decodeRectForKey:@"frame"]; - _stringSize = [aDecoder decodeSizeForKey:@"stringSize"]; - _currentStep = [aDecoder decodeIntegerForKey:@"currentStep"]; - _isPlaceholder = [aDecoder decodeBoolForKey:@"isPlaceholder"]; - _tabState = [aDecoder decodeIntegerForKey:@"tabState"]; - _closeButtonTrackingTag = [aDecoder decodeIntegerForKey:@"closeButtonTrackingTag"]; - _cellTrackingTag = [aDecoder decodeIntegerForKey:@"cellTrackingTag"]; - _closeButtonOver = [aDecoder decodeBoolForKey:@"closeButtonOver"]; - _closeButtonPressed = [aDecoder decodeBoolForKey:@"closeButtonPressed"]; - _indicator = [aDecoder decodeObjectForKey:@"indicator"]; - _isInOverflowMenu = [aDecoder decodeBoolForKey:@"isInOverflowMenu"]; - _hasCloseButton = [aDecoder decodeBoolForKey:@"hasCloseButton"]; - _isCloseButtonSuppressed = [aDecoder decodeBoolForKey:@"isCloseButtonSuppressed"]; - _hasIcon = [aDecoder decodeBoolForKey:@"hasIcon"]; - _hasLargeImage = [aDecoder decodeBoolForKey:@"hasLargeImage"]; - _count = [aDecoder decodeIntegerForKey:@"count"]; - _isEdited = [aDecoder decodeBoolForKey:@"isEdited"]; - } - } - return self; +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeRect:_frame forKey:@"frame"]; + [aCoder encodeSize:_stringSize forKey:@"stringSize"]; + [aCoder encodeInteger:_currentStep forKey:@"currentStep"]; + [aCoder encodeBool:_isPlaceholder forKey:@"isPlaceholder"]; + [aCoder encodeInteger:_tabState forKey:@"tabState"]; + [aCoder encodeInteger:_closeButtonTrackingTag forKey:@"closeButtonTrackingTag"]; + [aCoder encodeInteger:_cellTrackingTag forKey:@"cellTrackingTag"]; + [aCoder encodeBool:_closeButtonOver forKey:@"closeButtonOver"]; + [aCoder encodeBool:_closeButtonPressed forKey:@"closeButtonPressed"]; + [aCoder encodeObject:_indicator forKey:@"indicator"]; + [aCoder encodeBool:_isInOverflowMenu forKey:@"isInOverflowMenu"]; + [aCoder encodeBool:_hasCloseButton forKey:@"hasCloseButton"]; + [aCoder encodeBool:_isCloseButtonSuppressed forKey:@"isCloseButtonSuppressed"]; + [aCoder encodeBool:_hasIcon forKey:@"hasIcon"]; + [aCoder encodeBool:_hasLargeImage forKey:@"hasLargeImage"]; + [aCoder encodeInteger:_count forKey:@"count"]; + [aCoder encodeBool:_isEdited forKey:@"isEdited"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _frame = [aDecoder decodeRectForKey:@"frame"]; + _stringSize = [aDecoder decodeSizeForKey:@"stringSize"]; + _currentStep = [aDecoder decodeIntegerForKey:@"currentStep"]; + _isPlaceholder = [aDecoder decodeBoolForKey:@"isPlaceholder"]; + _tabState = [aDecoder decodeIntegerForKey:@"tabState"]; + _closeButtonTrackingTag = [aDecoder decodeIntegerForKey:@"closeButtonTrackingTag"]; + _cellTrackingTag = [aDecoder decodeIntegerForKey:@"cellTrackingTag"]; + _closeButtonOver = [aDecoder decodeBoolForKey:@"closeButtonOver"]; + _closeButtonPressed = [aDecoder decodeBoolForKey:@"closeButtonPressed"]; + _indicator = [aDecoder decodeObjectForKey:@"indicator"]; + _isInOverflowMenu = [aDecoder decodeBoolForKey:@"isInOverflowMenu"]; + _hasCloseButton = [aDecoder decodeBoolForKey:@"hasCloseButton"]; + _isCloseButtonSuppressed = [aDecoder decodeBoolForKey:@"isCloseButtonSuppressed"]; + _hasIcon = [aDecoder decodeBoolForKey:@"hasIcon"]; + _hasLargeImage = [aDecoder decodeBoolForKey:@"hasLargeImage"]; + _count = [aDecoder decodeIntegerForKey:@"count"]; + _isEdited = [aDecoder decodeBoolForKey:@"isEdited"]; + } + } + return self; } #pragma mark - #pragma mark Accessibility --(BOOL)accessibilityIsIgnored { - return NO; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute { - id attributeValue = nil; - - if([attribute isEqualToString: NSAccessibilityRoleAttribute]) { - attributeValue = NSAccessibilityButtonRole; - } else if([attribute isEqualToString: NSAccessibilityHelpAttribute]) { - if([[[self controlView] delegate] respondsToSelector:@selector(accessibilityStringForTabView:objectCount:)]) { - attributeValue = [NSString stringWithFormat:@"%@, %lu %@", [self stringValue], - (unsigned long)[self count], - [[[self controlView] delegate] accessibilityStringForTabView:[[self controlView] tabView] objectCount:[self count]]]; - } else { - attributeValue = [self stringValue]; - } - } else if([attribute isEqualToString: NSAccessibilityFocusedAttribute]) { - attributeValue = [NSNumber numberWithBool:([self tabState] == 2)]; - } else { - attributeValue = [super accessibilityAttributeValue:attribute]; - } - - return attributeValue; +- (BOOL)accessibilityIsIgnored +{ + return NO; } -- (NSArray *)accessibilityActionNames { - static NSArray *actions; +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + id attributeValue = nil; + + if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { + attributeValue = NSAccessibilityButtonRole; + } else if ([attribute isEqualToString:NSAccessibilityHelpAttribute]) { + if ([[[self controlView] delegate] respondsToSelector:@selector(accessibilityStringForTabView:objectCount:)]) { + attributeValue = [NSString stringWithFormat:@"%@, %lu %@", [self stringValue], + (unsigned long)[self count], + [[[self controlView] delegate] accessibilityStringForTabView:[[self controlView] tabView] + objectCount:[self count]]]; + } else { + attributeValue = [self stringValue]; + } + } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { + attributeValue = [NSNumber numberWithBool:([self tabState] == 2)]; + } else { + attributeValue = [super accessibilityAttributeValue:attribute]; + } + + return attributeValue; +} + +- (NSArray *)accessibilityActionNames +{ + static NSArray *actions; - if(!actions) { - actions = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction, nil]; - } - return actions; + if (!actions) { + actions = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction, nil]; + } + return actions; } -- (NSString *)accessibilityActionDescription:(NSString *)action { - return NSAccessibilityActionDescription(action); +- (NSString *)accessibilityActionDescription:(NSString *)action +{ + return NSAccessibilityActionDescription(action); } -- (void)accessibilityPerformAction:(NSString *)action { - if([action isEqualToString:NSAccessibilityPressAction]) { - // this tab was selected - [_controlView performSelector:@selector(tabClick:) withObject:self]; - } +- (void)accessibilityPerformAction:(NSString *)action +{ + if ([action isEqualToString:NSAccessibilityPressAction]) { + // this tab was selected + [_controlView performSelector:@selector(tabClick:) withObject:self]; + } } -- (id)accessibilityHitTest:(NSPoint)point { - return NSAccessibilityUnignoredAncestor(self); +- (id)accessibilityHitTest:(NSPoint)point +{ + return NSAccessibilityUnignoredAncestor(self); } -- (id)accessibilityFocusedUIElement:(NSPoint)point { - return NSAccessibilityUnignoredAncestor(self); +- (id)accessibilityFocusedUIElement:(NSPoint)point +{ + return NSAccessibilityUnignoredAncestor(self); } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabBarControl.m b/frontends/cocoa/PSMTabBarControl/PSMTabBarControl.m index 01df769f1..0d6a2d7bc 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabBarControl.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabBarControl.m @@ -35,11 +35,11 @@ + (NSBundle *)bundle { - static NSBundle *bundle = nil; - if(!bundle) { - bundle = [NSBundle bundleForClass:[PSMTabBarControl class]]; - } - return bundle; + static NSBundle *bundle = nil; + if (!bundle) { + bundle = [NSBundle bundleForClass:[PSMTabBarControl class]]; + } + return bundle; } /*! @@ -49,8 +49,9 @@ @returns Returns the amount of space for cells. */ -- (CGFloat)availableCellWidth { - return [self frame].size.width - [style leftMarginForTabBarControl] - [style rightMarginForTabBarControl] - _resizeAreaCompensation; +- (CGFloat)availableCellWidth +{ + return [self frame].size.width - [style leftMarginForTabBarControl] - [style rightMarginForTabBarControl] - _resizeAreaCompensation; } /*! @@ -60,1249 +61,1328 @@ @returns Returns a basic rect for a tab cell. */ -- (NSRect)genericCellRect { - NSRect aRect = [self frame]; - aRect.origin.x = [style leftMarginForTabBarControl]; - aRect.origin.y = 0.0; - aRect.size.width = [self availableCellWidth]; - aRect.size.height = [style tabCellHeight]; - return aRect; +- (NSRect)genericCellRect +{ + NSRect aRect = [self frame]; + aRect.origin.x = [style leftMarginForTabBarControl]; + aRect.origin.y = 0.0; + aRect.size.width = [self availableCellWidth]; + aRect.size.height = [style tabCellHeight]; + return aRect; } #pragma mark - #pragma mark Constructor/destructor -- (void)initAddedProperties { - _cells = [[NSMutableArray alloc] initWithCapacity:10]; - _controller = [[PSMTabBarController alloc] initWithTabBarControl:self]; - _animationTimer = nil; - - // default config - _currentStep = kPSMIsNotBeingResized; - _orientation = PSMTabBarHorizontalOrientation; - _canCloseOnlyTab = NO; - _disableTabClose = NO; - _showAddTabButton = NO; - _hideForSingleTab = NO; - _sizeCellsToFit = NO; - _isHidden = NO; - _awakenedFromNib = NO; - _automaticallyAnimates = NO; - _useOverflowMenu = YES; - _allowsBackgroundTabClosing = YES; - _allowsResizing = NO; - _selectsTabsOnMouseDown = NO; - _alwaysShowActiveTab = NO; - _allowsScrubbing = NO; - _cellMinWidth = 100; - _cellMaxWidth = 280; - _cellOptimumWidth = 130; - _tearOffStyle = PSMTabBarTearOffAlphaWindow; - style = [[[[self class] defaultStyleClass] alloc] init]; - - // the overflow button/menu - NSRect overflowButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 0, [style rightMarginForTabBarControl] - 1, [self frame].size.height); - _overflowPopUpButton = [[PSMOverflowPopUpButton alloc] initWithFrame:overflowButtonRect pullsDown:YES]; - [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; - [_overflowPopUpButton setHidden:YES]; - [self addSubview:_overflowPopUpButton]; - [self _positionOverflowMenu]; - - // new tab button - NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0, 16.0, 16.0); - _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; - if(_addTabButton) { - NSImage *newButtonImage = [style addTabButtonImage]; - if(newButtonImage) { - [_addTabButton setUsualImage:newButtonImage]; - } - newButtonImage = [style addTabButtonPressedImage]; - if(newButtonImage) { - [_addTabButton setAlternateImage:newButtonImage]; - } - newButtonImage = [style addTabButtonRolloverImage]; - if(newButtonImage) { - [_addTabButton setRolloverImage:newButtonImage]; - } - [_addTabButton setTitle:@""]; - [_addTabButton setImagePosition:NSImageOnly]; - [_addTabButton setButtonType:NSMomentaryChangeButton]; - [_addTabButton setBordered:NO]; - [_addTabButton setBezelStyle:NSShadowlessSquareBezelStyle]; - [self addSubview:_addTabButton]; - - if(_showAddTabButton) { - [_addTabButton setHidden:NO]; - } else { - [_addTabButton setHidden:YES]; - } - [_addTabButton setNeedsDisplay:YES]; - } -} - -+ (Class) defaultStyleClass -{ - return [PSMUnifiedTabStyle class]; -} - -- (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if(self) { - // Initialization - [self initAddedProperties]; - [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; - - // resize - [self setPostsFrameChangedNotifications:YES]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; - } - [self setTarget:self]; - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - //stop any animations that may be running - [_animationTimer invalidate]; - - [_showHideAnimationTimer invalidate]; - - //Also unwind the spring, if it's wound. - [_springTimer invalidate]; - - //unbind all the items to prevent crashing - //not sure if this is necessary or not - // http://code.google.com/p/maccode/issues/detail?id=35 - NSEnumerator *enumerator = [[_cells copy] objectEnumerator]; - PSMTabBarCell *nextCell; - while((nextCell = [enumerator nextObject])) { - [self removeTabForCell:nextCell]; - } - - [self unregisterDraggedTypes]; -} - -- (void)awakeFromNib { - // build cells from existing tab view items - NSArray *existingItems = [tabView tabViewItems]; - NSEnumerator *e = [existingItems objectEnumerator]; - NSTabViewItem *item; - while((item = [e nextObject])) { - if(![[self representedTabViewItems] containsObject:item]) { - [self addTabViewItem:item]; - } - } -} - -- (void)viewWillMoveToWindow:(NSWindow *)aWindow { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; - [center removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; - [center removeObserver:self name:NSWindowDidUpdateNotification object:nil]; - [center removeObserver:self name:NSWindowDidMoveNotification object:nil]; - - if(_showHideAnimationTimer) { - [_showHideAnimationTimer invalidate]; - _showHideAnimationTimer = nil; - } - - if(aWindow) { - [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidBecomeKeyNotification object:aWindow]; - [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidResignKeyNotification object:aWindow]; - [center addObserver:self selector:@selector(windowDidUpdate:) name:NSWindowDidUpdateNotification object:aWindow]; - [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:aWindow]; - } -} - -- (void)windowStatusDidChange:(NSNotification *)notification { - [self setNeedsDisplay:YES]; +- (void)initAddedProperties +{ + _cells = [[NSMutableArray alloc] initWithCapacity:10]; + _controller = [[PSMTabBarController alloc] initWithTabBarControl:self]; + _animationTimer = nil; + + // default config + _currentStep = kPSMIsNotBeingResized; + _orientation = PSMTabBarHorizontalOrientation; + _canCloseOnlyTab = NO; + _disableTabClose = NO; + _showAddTabButton = NO; + _hideForSingleTab = NO; + _sizeCellsToFit = NO; + _isHidden = NO; + _awakenedFromNib = NO; + _automaticallyAnimates = NO; + _useOverflowMenu = YES; + _allowsBackgroundTabClosing = YES; + _allowsResizing = NO; + _selectsTabsOnMouseDown = NO; + _alwaysShowActiveTab = NO; + _allowsScrubbing = NO; + _cellMinWidth = 100; + _cellMaxWidth = 280; + _cellOptimumWidth = 130; + _tearOffStyle = PSMTabBarTearOffAlphaWindow; + style = [[[[self class] defaultStyleClass] alloc] init]; + + // the overflow button/menu + NSRect overflowButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 0, [style rightMarginForTabBarControl] - 1, [self frame].size.height); + _overflowPopUpButton = [[PSMOverflowPopUpButton alloc] initWithFrame:overflowButtonRect pullsDown:YES]; + [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; + [_overflowPopUpButton setHidden:YES]; + [self addSubview:_overflowPopUpButton]; + [self _positionOverflowMenu]; + + // new tab button + NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0, 16.0, 16.0); + _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; + if (_addTabButton) { + NSImage *newButtonImage = [style addTabButtonImage]; + if (newButtonImage) { + [_addTabButton setUsualImage:newButtonImage]; + } + newButtonImage = [style addTabButtonPressedImage]; + if (newButtonImage) { + [_addTabButton setAlternateImage:newButtonImage]; + } + newButtonImage = [style addTabButtonRolloverImage]; + if (newButtonImage) { + [_addTabButton setRolloverImage:newButtonImage]; + } + [_addTabButton setTitle:@""]; + [_addTabButton setImagePosition:NSImageOnly]; + [_addTabButton setButtonType:NSMomentaryChangeButton]; + [_addTabButton setBordered:NO]; + [_addTabButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [self addSubview:_addTabButton]; + + if (_showAddTabButton) { + [_addTabButton setHidden:NO]; + } else { + [_addTabButton setHidden:YES]; + } + [_addTabButton setNeedsDisplay:YES]; + } +} + ++ (Class)defaultStyleClass +{ + return [PSMUnifiedTabStyle class]; +} + +- (id)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization + [self initAddedProperties]; + [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; + + // resize + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; + } + [self setTarget:self]; + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + //stop any animations that may be running + [_animationTimer invalidate]; + + [_showHideAnimationTimer invalidate]; + + //Also unwind the spring, if it's wound. + [_springTimer invalidate]; + + //unbind all the items to prevent crashing + //not sure if this is necessary or not + // http://code.google.com/p/maccode/issues/detail?id=35 + NSEnumerator *enumerator = [[_cells copy] objectEnumerator]; + PSMTabBarCell *nextCell; + while ((nextCell = [enumerator nextObject])) { + [self removeTabForCell:nextCell]; + } + + [self unregisterDraggedTypes]; +} + +- (void)awakeFromNib +{ + // build cells from existing tab view items + NSArray *existingItems = [tabView tabViewItems]; + NSEnumerator *e = [existingItems objectEnumerator]; + NSTabViewItem *item; + while ((item = [e nextObject])) { + if (![[self representedTabViewItems] containsObject:item]) { + [self addTabViewItem:item]; + } + } +} + +- (void)viewWillMoveToWindow:(NSWindow *)aWindow +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; + [center removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; + [center removeObserver:self name:NSWindowDidUpdateNotification object:nil]; + [center removeObserver:self name:NSWindowDidMoveNotification object:nil]; + + if (_showHideAnimationTimer) { + [_showHideAnimationTimer invalidate]; + _showHideAnimationTimer = nil; + } + + if (aWindow) { + [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidBecomeKeyNotification object:aWindow]; + [center addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidResignKeyNotification object:aWindow]; + [center addObserver:self selector:@selector(windowDidUpdate:) name:NSWindowDidUpdateNotification object:aWindow]; + [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:aWindow]; + } +} + +- (void)windowStatusDidChange:(NSNotification *)notification +{ + [self setNeedsDisplay:YES]; } #pragma mark - #pragma mark Accessors -- (NSMutableArray *)cells { - return _cells; +- (NSMutableArray *)cells +{ + return _cells; } -- (NSEvent *)lastMouseDownEvent { - return _lastMouseDownEvent; +- (NSEvent *)lastMouseDownEvent +{ + return _lastMouseDownEvent; } -- (void)setLastMouseDownEvent:(NSEvent *)event { - _lastMouseDownEvent = event; +- (void)setLastMouseDownEvent:(NSEvent *)event +{ + _lastMouseDownEvent = event; } -- (id)delegate { - return delegate; +- (id)delegate +{ + return delegate; } -- (void)setDelegate:(id)object { - delegate = object; +- (void)setDelegate:(id)object +{ + delegate = object; - NSMutableArray *types = [NSMutableArray arrayWithObject:@"PSMTabBarControlItemPBType"]; + NSMutableArray *types = [NSMutableArray arrayWithObject:@"PSMTabBarControlItemPBType"]; - //Update the allowed drag types - if([self delegate] && [[self delegate] respondsToSelector:@selector(allowedDraggedTypesForTabView:)]) { - [types addObjectsFromArray:[[self delegate] allowedDraggedTypesForTabView:tabView]]; - } - [self unregisterDraggedTypes]; - [self registerForDraggedTypes:types]; + //Update the allowed drag types + if ([self delegate] && [[self delegate] respondsToSelector:@selector(allowedDraggedTypesForTabView:)]) { + [types addObjectsFromArray:[[self delegate] allowedDraggedTypesForTabView:tabView]]; + } + [self unregisterDraggedTypes]; + [self registerForDraggedTypes:types]; } -- (NSTabView *)tabView { - return tabView; +- (NSTabView *)tabView +{ + return tabView; } -- (void)setTabView:(NSTabView *)view { - tabView = view; +- (void)setTabView:(NSTabView *)view +{ + tabView = view; } -- (id)style { - return style; +- (id)style +{ + return style; } -- (NSString *)styleName { - return [style name]; +- (NSString *)styleName +{ + return [style name]; } -- (void)setStyle:(id )newStyle { - if(style != newStyle) { +- (void)setStyle:(id)newStyle +{ + if (style != newStyle) { - // restyle add tab button - if(_addTabButton) { - NSImage *newButtonImage = [style addTabButtonImage]; - if(newButtonImage) { - [_addTabButton setUsualImage:newButtonImage]; - } + // restyle add tab button + if (_addTabButton) { + NSImage *newButtonImage = [style addTabButtonImage]; + if (newButtonImage) { + [_addTabButton setUsualImage:newButtonImage]; + } - newButtonImage = [style addTabButtonPressedImage]; - if(newButtonImage) { - [_addTabButton setAlternateImage:newButtonImage]; - } + newButtonImage = [style addTabButtonPressedImage]; + if (newButtonImage) { + [_addTabButton setAlternateImage:newButtonImage]; + } - newButtonImage = [style addTabButtonRolloverImage]; - if(newButtonImage) { - [_addTabButton setRolloverImage:newButtonImage]; - } - } + newButtonImage = [style addTabButtonRolloverImage]; + if (newButtonImage) { + [_addTabButton setRolloverImage:newButtonImage]; + } + } - [self update]; - } + [self update]; + } } -- (void)setStyleNamed:(NSString *)name { - - Class styleClass = NSClassFromString( [NSString stringWithFormat: @"PSM%@TabStyle", [name capitalizedString]] ); - if (styleClass == Nil) { - styleClass = object_getClass([PSMTabBarControl defaultStyleClass]); - } +- (void)setStyleNamed:(NSString *)name +{ + + Class styleClass = NSClassFromString([NSString stringWithFormat:@"PSM%@TabStyle", [name capitalizedString]]); + if (styleClass == Nil) { + styleClass = object_getClass([PSMTabBarControl defaultStyleClass]); + } - id newStyle = [[styleClass alloc] init]; - [self setStyle:newStyle]; + id newStyle = [[styleClass alloc] init]; + [self setStyle:newStyle]; } -- (PSMTabBarOrientation)orientation { - return _orientation; +- (PSMTabBarOrientation)orientation +{ + return _orientation; } -- (void)setOrientation:(PSMTabBarOrientation)value { - PSMTabBarOrientation lastOrientation = _orientation; - _orientation = value; +- (void)setOrientation:(PSMTabBarOrientation)value +{ + PSMTabBarOrientation lastOrientation = _orientation; + _orientation = value; - if(_tabBarWidth < 10) { - _tabBarWidth = 120; - } + if (_tabBarWidth < 10) { + _tabBarWidth = 120; + } - if (lastOrientation != _orientation) { - [[self style] setOrientation:_orientation]; + if (lastOrientation != _orientation) { + [[self style] setOrientation:_orientation]; - [self _positionOverflowMenu]; //move the overflow popup button to the right place - [self update:NO]; - } + [self _positionOverflowMenu]; //move the overflow popup button to the right place + [self update:NO]; + } } -- (BOOL)canCloseOnlyTab { - return _canCloseOnlyTab; +- (BOOL)canCloseOnlyTab +{ + return _canCloseOnlyTab; } -- (void)setCanCloseOnlyTab:(BOOL)value { - _canCloseOnlyTab = value; - if([_cells count] == 1) { - [self update]; - } +- (void)setCanCloseOnlyTab:(BOOL)value +{ + _canCloseOnlyTab = value; + if ([_cells count] == 1) { + [self update]; + } } -- (BOOL)disableTabClose { - return _disableTabClose; +- (BOOL)disableTabClose +{ + return _disableTabClose; } -- (void)setDisableTabClose:(BOOL)value { - _disableTabClose = value; - [self update]; +- (void)setDisableTabClose:(BOOL)value +{ + _disableTabClose = value; + [self update]; } -- (BOOL)hideForSingleTab { - return _hideForSingleTab; +- (BOOL)hideForSingleTab +{ + return _hideForSingleTab; } -- (void)setHideForSingleTab:(BOOL)value { - _hideForSingleTab = value; - [self update]; +- (void)setHideForSingleTab:(BOOL)value +{ + _hideForSingleTab = value; + [self update]; } -- (BOOL)showAddTabButton { - return _showAddTabButton; +- (BOOL)showAddTabButton +{ + return _showAddTabButton; } -- (void)setShowAddTabButton:(BOOL)value { - _showAddTabButton = value; - if(!NSIsEmptyRect([_controller addButtonRect])) { - [_addTabButton setFrame:[_controller addButtonRect]]; - } +- (void)setShowAddTabButton:(BOOL)value +{ + _showAddTabButton = value; + if (!NSIsEmptyRect([_controller addButtonRect])) { + [_addTabButton setFrame:[_controller addButtonRect]]; + } - [_addTabButton setHidden:!_showAddTabButton]; - [_addTabButton setNeedsDisplay:YES]; + [_addTabButton setHidden:!_showAddTabButton]; + [_addTabButton setNeedsDisplay:YES]; - [self update]; + [self update]; } -- (NSInteger)cellMinWidth { - return _cellMinWidth; +- (NSInteger)cellMinWidth +{ + return _cellMinWidth; } -- (void)setCellMinWidth:(NSInteger)value { - _cellMinWidth = value; - [self update]; +- (void)setCellMinWidth:(NSInteger)value +{ + _cellMinWidth = value; + [self update]; } -- (NSInteger)cellMaxWidth { - return _cellMaxWidth; +- (NSInteger)cellMaxWidth +{ + return _cellMaxWidth; } -- (void)setCellMaxWidth:(NSInteger)value { - _cellMaxWidth = value; - [self update]; +- (void)setCellMaxWidth:(NSInteger)value +{ + _cellMaxWidth = value; + [self update]; } -- (NSInteger)cellOptimumWidth { - return _cellOptimumWidth; +- (NSInteger)cellOptimumWidth +{ + return _cellOptimumWidth; } -- (void)setCellOptimumWidth:(NSInteger)value { - _cellOptimumWidth = value; - [self update]; +- (void)setCellOptimumWidth:(NSInteger)value +{ + _cellOptimumWidth = value; + [self update]; } -- (BOOL)sizeCellsToFit { - return _sizeCellsToFit; +- (BOOL)sizeCellsToFit +{ + return _sizeCellsToFit; } -- (void)setSizeCellsToFit:(BOOL)value { - _sizeCellsToFit = value; - [self update]; +- (void)setSizeCellsToFit:(BOOL)value +{ + _sizeCellsToFit = value; + [self update]; } -- (BOOL)useOverflowMenu { - return _useOverflowMenu; +- (BOOL)useOverflowMenu +{ + return _useOverflowMenu; } -- (void)setUseOverflowMenu:(BOOL)value { - _useOverflowMenu = value; - [self update]; +- (void)setUseOverflowMenu:(BOOL)value +{ + _useOverflowMenu = value; + [self update]; } -- (PSMRolloverButton *)addTabButton { - return _addTabButton; +- (PSMRolloverButton *)addTabButton +{ + return _addTabButton; } -- (PSMOverflowPopUpButton *)overflowPopUpButton { - return _overflowPopUpButton; +- (PSMOverflowPopUpButton *)overflowPopUpButton +{ + return _overflowPopUpButton; } -- (BOOL)allowsBackgroundTabClosing { - return _allowsBackgroundTabClosing; +- (BOOL)allowsBackgroundTabClosing +{ + return _allowsBackgroundTabClosing; } -- (void)setAllowsBackgroundTabClosing:(BOOL)value { - _allowsBackgroundTabClosing = value; +- (void)setAllowsBackgroundTabClosing:(BOOL)value +{ + _allowsBackgroundTabClosing = value; } -- (BOOL)allowsResizing { - return _allowsResizing; +- (BOOL)allowsResizing +{ + return _allowsResizing; } -- (void)setAllowsResizing:(BOOL)value { - _allowsResizing = value; +- (void)setAllowsResizing:(BOOL)value +{ + _allowsResizing = value; } -- (BOOL)selectsTabsOnMouseDown { - return _selectsTabsOnMouseDown; +- (BOOL)selectsTabsOnMouseDown +{ + return _selectsTabsOnMouseDown; } -- (void)setSelectsTabsOnMouseDown:(BOOL)value { - _selectsTabsOnMouseDown = value; +- (void)setSelectsTabsOnMouseDown:(BOOL)value +{ + _selectsTabsOnMouseDown = value; } -- (BOOL)automaticallyAnimates { - return _automaticallyAnimates; +- (BOOL)automaticallyAnimates +{ + return _automaticallyAnimates; } -- (void)setAutomaticallyAnimates:(BOOL)value { - _automaticallyAnimates = value; +- (void)setAutomaticallyAnimates:(BOOL)value +{ + _automaticallyAnimates = value; } -- (BOOL)alwaysShowActiveTab { - return _alwaysShowActiveTab; +- (BOOL)alwaysShowActiveTab +{ + return _alwaysShowActiveTab; } -- (void)setAlwaysShowActiveTab:(BOOL)value { - _alwaysShowActiveTab = value; +- (void)setAlwaysShowActiveTab:(BOOL)value +{ + _alwaysShowActiveTab = value; } -- (BOOL)allowsScrubbing { - return _allowsScrubbing; +- (BOOL)allowsScrubbing +{ + return _allowsScrubbing; } -- (void)setAllowsScrubbing:(BOOL)value { - _allowsScrubbing = value; +- (void)setAllowsScrubbing:(BOOL)value +{ + _allowsScrubbing = value; } -- (PSMTabBarTearOffStyle)tearOffStyle { - return _tearOffStyle; +- (PSMTabBarTearOffStyle)tearOffStyle +{ + return _tearOffStyle; } -- (void)setTearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle { - _tearOffStyle = tearOffStyle; +- (void)setTearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle +{ + _tearOffStyle = tearOffStyle; } #pragma mark - #pragma mark Functionality -- (void)addTabViewItem:(NSTabViewItem *)item { - // create cell - PSMTabBarCell *cell = [[PSMTabBarCell alloc] initWithControlView:self]; - NSRect cellRect, lastCellFrame; - if([_cells lastObject] != nil) { - cellRect = lastCellFrame = [[_cells lastObject] frame]; - } else { - cellRect = lastCellFrame = NSZeroRect; - } - - if([self orientation] == PSMTabBarHorizontalOrientation) { - cellRect = [self genericCellRect]; - cellRect.size.width = 30; - cellRect.origin.x = lastCellFrame.origin.x + lastCellFrame.size.width; - } else { - cellRect = /*lastCellFrame*/ [self genericCellRect]; - cellRect.size.width = lastCellFrame.size.width; - cellRect.size.height = 0; - cellRect.origin.y = lastCellFrame.origin.y + lastCellFrame.size.height; - } - - [cell setRepresentedObject:item]; - [cell setFrame:cellRect]; - - // bind it up - [self bindPropertiesForCell:cell andTabViewItem:item]; - - // add to collection - [_cells addObject:cell]; - if([_cells count] == (NSUInteger)[tabView numberOfTabViewItems]) { - [self update]; // don't update unless all are accounted for! - } -} - -- (void)removeTabForCell:(PSMTabBarCell *)cell { - NSTabViewItem *item = [cell representedObject]; - - // unbind - [[cell indicator] unbind:@"animate"]; - [[cell indicator] unbind:@"hidden"]; - [cell unbind:@"hasIcon"]; - [cell unbind:@"hasLargeImage"]; - [cell unbind:@"title"]; - [cell unbind:@"count"]; - [cell unbind:@"countColor"]; - [cell unbind:@"isEdited"]; - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(isProcessing)]) { - [[item identifier] removeObserver:cell forKeyPath:@"isProcessing"]; - } - } - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(icon)]) { - [[item identifier] removeObserver:cell forKeyPath:@"icon"]; - } - } - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(objectCount)]) { - [[item identifier] removeObserver:cell forKeyPath:@"objectCount"]; - } - } - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(countColor)]) { - [[item identifier] removeObserver:cell forKeyPath:@"countColor"]; - } - } - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(largeImage)]) { - [[item identifier] removeObserver:cell forKeyPath:@"largeImage"]; - } - } - - if([item identifier] != nil) { - if([[item identifier] respondsToSelector:@selector(isEdited)]) { - [[item identifier] removeObserver:cell forKeyPath:@"isEdited"]; - } - } - - // stop watching identifier - [item removeObserver:self forKeyPath:@"identifier"]; - - // remove indicator - if([[self subviews] containsObject:[cell indicator]]) { - [[cell indicator] removeFromSuperview]; - } - // remove tracking - [[NSNotificationCenter defaultCenter] removeObserver:cell]; - - if([cell closeButtonTrackingTag] != 0) { - [self removeTrackingRect:[cell closeButtonTrackingTag]]; - [cell setCloseButtonTrackingTag:0]; - } - if([cell cellTrackingTag] != 0) { - [self removeTrackingRect:[cell cellTrackingTag]]; - [cell setCellTrackingTag:0]; - } - - // pull from collection - [_cells removeObject:cell]; - - [self update]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - // did the tab's identifier change? - if([keyPath isEqualToString:@"identifier"]) { - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - if([cell representedObject] == object) { - [self _bindPropertiesForCell:cell andTabViewItem:object]; - } - } - } +- (void)addTabViewItem:(NSTabViewItem *)item +{ + // create cell + PSMTabBarCell *cell = [[PSMTabBarCell alloc] initWithControlView:self]; + NSRect cellRect, lastCellFrame; + if ([_cells lastObject] != nil) { + cellRect = lastCellFrame = [[_cells lastObject] frame]; + } else { + cellRect = lastCellFrame = NSZeroRect; + } + + if ([self orientation] == PSMTabBarHorizontalOrientation) { + cellRect = [self genericCellRect]; + cellRect.size.width = 30; + cellRect.origin.x = lastCellFrame.origin.x + lastCellFrame.size.width; + } else { + cellRect = /*lastCellFrame*/ [self genericCellRect]; + cellRect.size.width = lastCellFrame.size.width; + cellRect.size.height = 0; + cellRect.origin.y = lastCellFrame.origin.y + lastCellFrame.size.height; + } + + [cell setRepresentedObject:item]; + [cell setFrame:cellRect]; + + // bind it up + [self bindPropertiesForCell:cell andTabViewItem:item]; + + // add to collection + [_cells addObject:cell]; + if ([_cells count] == (NSUInteger)[tabView numberOfTabViewItems]) { + [self update]; // don't update unless all are accounted for! + } +} + +- (void)removeTabForCell:(PSMTabBarCell *)cell +{ + NSTabViewItem *item = [cell representedObject]; + + // unbind + [[cell indicator] unbind:@"animate"]; + [[cell indicator] unbind:@"hidden"]; + [cell unbind:@"hasIcon"]; + [cell unbind:@"hasLargeImage"]; + [cell unbind:@"title"]; + [cell unbind:@"count"]; + [cell unbind:@"countColor"]; + [cell unbind:@"isEdited"]; + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(isProcessing)]) { + [[item identifier] removeObserver:cell forKeyPath:@"isProcessing"]; + } + } + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(icon)]) { + [[item identifier] removeObserver:cell forKeyPath:@"icon"]; + } + } + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(objectCount)]) { + [[item identifier] removeObserver:cell forKeyPath:@"objectCount"]; + } + } + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(countColor)]) { + [[item identifier] removeObserver:cell forKeyPath:@"countColor"]; + } + } + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(largeImage)]) { + [[item identifier] removeObserver:cell forKeyPath:@"largeImage"]; + } + } + + if ([item identifier] != nil) { + if ([[item identifier] respondsToSelector:@selector(isEdited)]) { + [[item identifier] removeObserver:cell forKeyPath:@"isEdited"]; + } + } + + // stop watching identifier + [item removeObserver:self forKeyPath:@"identifier"]; + + // remove indicator + if ([[self subviews] containsObject:[cell indicator]]) { + [[cell indicator] removeFromSuperview]; + } + // remove tracking + [[NSNotificationCenter defaultCenter] removeObserver:cell]; + + if ([cell closeButtonTrackingTag] != 0) { + [self removeTrackingRect:[cell closeButtonTrackingTag]]; + [cell setCloseButtonTrackingTag:0]; + } + if ([cell cellTrackingTag] != 0) { + [self removeTrackingRect:[cell cellTrackingTag]]; + [cell setCellTrackingTag:0]; + } + + // pull from collection + [_cells removeObject:cell]; + + [self update]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // did the tab's identifier change? + if ([keyPath isEqualToString:@"identifier"]) { + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + if ([cell representedObject] == object) { + [self _bindPropertiesForCell:cell andTabViewItem:object]; + } + } + } } #pragma mark - #pragma mark Hide/Show -- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate { - if(!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide) || (_currentStep != kPSMIsNotBeingResized)) { - return; - } - - [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; - - _isHidden = hide; - _currentStep = 0; - if(!animate) { - _currentStep = (NSInteger)kPSMHideAnimationSteps; - } - - if(hide) { - [_overflowPopUpButton removeFromSuperview]; - [_addTabButton removeFromSuperview]; - } else if(!animate) { - [self addSubview:_overflowPopUpButton]; - [self addSubview:_addTabButton]; - } - - CGFloat partnerOriginalSize, partnerOriginalOrigin, myOriginalSize, myOriginalOrigin, partnerTargetSize, partnerTargetOrigin, myTargetSize, myTargetOrigin; - - // target values for partner - if([self orientation] == PSMTabBarHorizontalOrientation) { - // current (original) values - myOriginalSize = [self frame].size.height; - myOriginalOrigin = [self frame].origin.y; - if(partnerView) { - partnerOriginalSize = [partnerView frame].size.height; - partnerOriginalOrigin = [partnerView frame].origin.y; - } else { - partnerOriginalSize = [[self window] frame].size.height; - partnerOriginalOrigin = [[self window] frame].origin.y; - } - - if(partnerView) { - // above or below me? - if((myOriginalOrigin - 22) > partnerOriginalOrigin) { - // partner is below me - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin + 21; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize + 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin - 21; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize - 21; - } - } else { - // partner is above me - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin - 21; - partnerTargetSize = partnerOriginalSize + 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin + 21; - partnerTargetSize = partnerOriginalSize - 21; - } - } - } else { - // for window movement - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin + 21; - partnerTargetSize = partnerOriginalSize - 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin - 21; - partnerTargetSize = partnerOriginalSize + 21; - } - } - } else { /* vertical */ - // current (original) values - myOriginalSize = [self frame].size.width; - myOriginalOrigin = [self frame].origin.x; - if(partnerView) { - partnerOriginalSize = [partnerView frame].size.width; - partnerOriginalOrigin = [partnerView frame].origin.x; - } else { - partnerOriginalSize = [[self window] frame].size.width; - partnerOriginalOrigin = [[self window] frame].origin.x; - } - - if(partnerView) { - //to the left or right? - if(myOriginalOrigin < partnerOriginalOrigin + partnerOriginalSize) { - // partner is to the left - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = 1; - partnerTargetOrigin = partnerOriginalOrigin - myOriginalSize + 1; - partnerTargetSize = partnerOriginalSize + myOriginalSize - 1; - _tabBarWidth = myOriginalSize; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize + _tabBarWidth; - partnerTargetOrigin = partnerOriginalOrigin + _tabBarWidth; - partnerTargetSize = partnerOriginalSize - _tabBarWidth; - } - } else { - // partner is to the right - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin + myOriginalSize; - myTargetSize = 1; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize + myOriginalSize; - _tabBarWidth = myOriginalSize; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin - _tabBarWidth; - myTargetSize = myOriginalSize + _tabBarWidth; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize - _tabBarWidth; - } - } - } else { - // for window movement - if(_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = 1; - partnerTargetOrigin = partnerOriginalOrigin + myOriginalSize - 1; - partnerTargetSize = partnerOriginalSize - myOriginalSize + 1; - _tabBarWidth = myOriginalSize; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = _tabBarWidth; - partnerTargetOrigin = partnerOriginalOrigin - _tabBarWidth + 1; - partnerTargetSize = partnerOriginalSize + _tabBarWidth - 1; - } - } - - if(!_isHidden && [[self delegate] respondsToSelector:@selector(desiredWidthForVerticalTabBar:)]) { - myTargetSize = [[self delegate] desiredWidthForVerticalTabBar:self]; - } - } - - NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:myOriginalOrigin], @"myOriginalOrigin", [NSNumber numberWithDouble:partnerOriginalOrigin], @"partnerOriginalOrigin", [NSNumber numberWithDouble:myOriginalSize], @"myOriginalSize", [NSNumber numberWithDouble:partnerOriginalSize], @"partnerOriginalSize", [NSNumber numberWithDouble:myTargetOrigin], @"myTargetOrigin", [NSNumber numberWithDouble:partnerTargetOrigin], @"partnerTargetOrigin", [NSNumber numberWithDouble:myTargetSize], @"myTargetSize", [NSNumber numberWithDouble:partnerTargetSize], @"partnerTargetSize", nil]; - if(_showHideAnimationTimer) { - [_showHideAnimationTimer invalidate]; - } - _showHideAnimationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateShowHide:) userInfo:userInfo repeats:YES]; -} - -- (void)animateShowHide:(NSTimer *)timer { - // moves the frame of the tab bar and window (or partner view) linearly to hide or show the tab bar - NSRect myFrame = [self frame]; - NSDictionary *userInfo = [timer userInfo]; - CGFloat myCurrentOrigin = ([[userInfo objectForKey:@"myOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"myTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"myOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); - CGFloat myCurrentSize = ([[userInfo objectForKey:@"myOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"myTargetSize"] doubleValue] - [[userInfo objectForKey:@"myOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); - CGFloat partnerCurrentOrigin = ([[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); - CGFloat partnerCurrentSize = ([[userInfo objectForKey:@"partnerOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetSize"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); - - NSRect myNewFrame; - if([self orientation] == PSMTabBarHorizontalOrientation) { - myNewFrame = NSMakeRect(myFrame.origin.x, myCurrentOrigin, myFrame.size.width, myCurrentSize); - } else { - myNewFrame = NSMakeRect(myCurrentOrigin, myFrame.origin.y, myCurrentSize, myFrame.size.height); - } - - if(partnerView) { - // resize self and view - NSRect resizeRect; - if([self orientation] == PSMTabBarHorizontalOrientation) { - resizeRect = NSMakeRect([partnerView frame].origin.x, partnerCurrentOrigin, [partnerView frame].size.width, partnerCurrentSize); - } else { - resizeRect = NSMakeRect(partnerCurrentOrigin, [partnerView frame].origin.y, partnerCurrentSize, [partnerView frame].size.height); - } - [partnerView setFrame:resizeRect]; - [partnerView setNeedsDisplay:YES]; - [self setFrame:myNewFrame]; - } else { - // resize self and window - NSRect resizeRect; - if([self orientation] == PSMTabBarHorizontalOrientation) { - resizeRect = NSMakeRect([[self window] frame].origin.x, partnerCurrentOrigin, [[self window] frame].size.width, partnerCurrentSize); - } else { - resizeRect = NSMakeRect(partnerCurrentOrigin, [[self window] frame].origin.y, partnerCurrentSize, [[self window] frame].size.height); - } - [[self window] setFrame:resizeRect display:YES]; - [self setFrame:myNewFrame]; - } - - // next - _currentStep++; - if(_currentStep == kPSMHideAnimationSteps + 1) { - _currentStep = kPSMIsNotBeingResized; - [self viewDidEndLiveResize]; - [self update:NO]; - - //send the delegate messages - if(_isHidden) { - if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { - [[self delegate] tabView:[self tabView] tabBarDidHide:self]; - } - } else { - [self addSubview:_overflowPopUpButton]; - [self addSubview:_addTabButton]; - - if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidUnhide:)]) { - [[self delegate] tabView:[self tabView] tabBarDidUnhide:self]; - } - } - - [_showHideAnimationTimer invalidate]; - _showHideAnimationTimer = nil; - } - [[self window] display]; -} - -- (BOOL)isTabBarHidden { - return _isHidden; -} - -- (BOOL)isAnimating { - return _animationTimer != nil; -} - -- (id)partnerView { - return partnerView; -} - -- (void)setPartnerView:(id)view { - partnerView = view; +- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate +{ + if (!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide) || (_currentStep != kPSMIsNotBeingResized)) { + return; + } + + [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + + _isHidden = hide; + _currentStep = 0; + if (!animate) { + _currentStep = (NSInteger)kPSMHideAnimationSteps; + } + + if (hide) { + [_overflowPopUpButton removeFromSuperview]; + [_addTabButton removeFromSuperview]; + } else if (!animate) { + [self addSubview:_overflowPopUpButton]; + [self addSubview:_addTabButton]; + } + + CGFloat partnerOriginalSize, partnerOriginalOrigin, myOriginalSize, myOriginalOrigin, partnerTargetSize, partnerTargetOrigin, myTargetSize, myTargetOrigin; + + // target values for partner + if ([self orientation] == PSMTabBarHorizontalOrientation) { + // current (original) values + myOriginalSize = [self frame].size.height; + myOriginalOrigin = [self frame].origin.y; + if (partnerView) { + partnerOriginalSize = [partnerView frame].size.height; + partnerOriginalOrigin = [partnerView frame].origin.y; + } else { + partnerOriginalSize = [[self window] frame].size.height; + partnerOriginalOrigin = [[self window] frame].origin.y; + } + + if (partnerView) { + // above or below me? + if ((myOriginalOrigin - 22) > partnerOriginalOrigin) { + // partner is below me + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin + 21; + myTargetSize = myOriginalSize - 21; + partnerTargetOrigin = partnerOriginalOrigin; + partnerTargetSize = partnerOriginalSize + 21; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin - 21; + myTargetSize = myOriginalSize + 21; + partnerTargetOrigin = partnerOriginalOrigin; + partnerTargetSize = partnerOriginalSize - 21; + } + } else { + // partner is above me + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin; + myTargetSize = myOriginalSize - 21; + partnerTargetOrigin = partnerOriginalOrigin - 21; + partnerTargetSize = partnerOriginalSize + 21; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin; + myTargetSize = myOriginalSize + 21; + partnerTargetOrigin = partnerOriginalOrigin + 21; + partnerTargetSize = partnerOriginalSize - 21; + } + } + } else { + // for window movement + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin; + myTargetSize = myOriginalSize - 21; + partnerTargetOrigin = partnerOriginalOrigin + 21; + partnerTargetSize = partnerOriginalSize - 21; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin; + myTargetSize = myOriginalSize + 21; + partnerTargetOrigin = partnerOriginalOrigin - 21; + partnerTargetSize = partnerOriginalSize + 21; + } + } + } else { /* vertical */ + // current (original) values + myOriginalSize = [self frame].size.width; + myOriginalOrigin = [self frame].origin.x; + if (partnerView) { + partnerOriginalSize = [partnerView frame].size.width; + partnerOriginalOrigin = [partnerView frame].origin.x; + } else { + partnerOriginalSize = [[self window] frame].size.width; + partnerOriginalOrigin = [[self window] frame].origin.x; + } + + if (partnerView) { + //to the left or right? + if (myOriginalOrigin < partnerOriginalOrigin + partnerOriginalSize) { + // partner is to the left + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin; + myTargetSize = 1; + partnerTargetOrigin = partnerOriginalOrigin - myOriginalSize + 1; + partnerTargetSize = partnerOriginalSize + myOriginalSize - 1; + _tabBarWidth = myOriginalSize; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin; + myTargetSize = myOriginalSize + _tabBarWidth; + partnerTargetOrigin = partnerOriginalOrigin + _tabBarWidth; + partnerTargetSize = partnerOriginalSize - _tabBarWidth; + } + } else { + // partner is to the right + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin + myOriginalSize; + myTargetSize = 1; + partnerTargetOrigin = partnerOriginalOrigin; + partnerTargetSize = partnerOriginalSize + myOriginalSize; + _tabBarWidth = myOriginalSize; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin - _tabBarWidth; + myTargetSize = myOriginalSize + _tabBarWidth; + partnerTargetOrigin = partnerOriginalOrigin; + partnerTargetSize = partnerOriginalSize - _tabBarWidth; + } + } + } else { + // for window movement + if (_isHidden) { + // I'm shrinking + myTargetOrigin = myOriginalOrigin; + myTargetSize = 1; + partnerTargetOrigin = partnerOriginalOrigin + myOriginalSize - 1; + partnerTargetSize = partnerOriginalSize - myOriginalSize + 1; + _tabBarWidth = myOriginalSize; + } else { + // I'm growing + myTargetOrigin = myOriginalOrigin; + myTargetSize = _tabBarWidth; + partnerTargetOrigin = partnerOriginalOrigin - _tabBarWidth + 1; + partnerTargetSize = partnerOriginalSize + _tabBarWidth - 1; + } + } + + if (!_isHidden && [[self delegate] respondsToSelector:@selector(desiredWidthForVerticalTabBar:)]) { + myTargetSize = [[self delegate] desiredWidthForVerticalTabBar:self]; + } + } + + NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:myOriginalOrigin], @"myOriginalOrigin", [NSNumber numberWithDouble:partnerOriginalOrigin], @"partnerOriginalOrigin", [NSNumber numberWithDouble:myOriginalSize], @"myOriginalSize", [NSNumber numberWithDouble:partnerOriginalSize], @"partnerOriginalSize", [NSNumber numberWithDouble:myTargetOrigin], @"myTargetOrigin", [NSNumber numberWithDouble:partnerTargetOrigin], @"partnerTargetOrigin", [NSNumber numberWithDouble:myTargetSize], @"myTargetSize", [NSNumber numberWithDouble:partnerTargetSize], @"partnerTargetSize", nil]; + if (_showHideAnimationTimer) { + [_showHideAnimationTimer invalidate]; + } + _showHideAnimationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateShowHide:) userInfo:userInfo repeats:YES]; +} + +- (void)animateShowHide:(NSTimer *)timer +{ + // moves the frame of the tab bar and window (or partner view) linearly to hide or show the tab bar + NSRect myFrame = [self frame]; + NSDictionary *userInfo = [timer userInfo]; + CGFloat myCurrentOrigin = ([[userInfo objectForKey:@"myOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"myTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"myOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat myCurrentSize = ([[userInfo objectForKey:@"myOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"myTargetSize"] doubleValue] - [[userInfo objectForKey:@"myOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat partnerCurrentOrigin = ([[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetOrigin"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalOrigin"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + CGFloat partnerCurrentSize = ([[userInfo objectForKey:@"partnerOriginalSize"] doubleValue] + (([[userInfo objectForKey:@"partnerTargetSize"] doubleValue] - [[userInfo objectForKey:@"partnerOriginalSize"] doubleValue]) * (_currentStep / kPSMHideAnimationSteps))); + + NSRect myNewFrame; + if ([self orientation] == PSMTabBarHorizontalOrientation) { + myNewFrame = NSMakeRect(myFrame.origin.x, myCurrentOrigin, myFrame.size.width, myCurrentSize); + } else { + myNewFrame = NSMakeRect(myCurrentOrigin, myFrame.origin.y, myCurrentSize, myFrame.size.height); + } + + if (partnerView) { + // resize self and view + NSRect resizeRect; + if ([self orientation] == PSMTabBarHorizontalOrientation) { + resizeRect = NSMakeRect([partnerView frame].origin.x, partnerCurrentOrigin, [partnerView frame].size.width, partnerCurrentSize); + } else { + resizeRect = NSMakeRect(partnerCurrentOrigin, [partnerView frame].origin.y, partnerCurrentSize, [partnerView frame].size.height); + } + [partnerView setFrame:resizeRect]; + [partnerView setNeedsDisplay:YES]; + [self setFrame:myNewFrame]; + } else { + // resize self and window + NSRect resizeRect; + if ([self orientation] == PSMTabBarHorizontalOrientation) { + resizeRect = NSMakeRect([[self window] frame].origin.x, partnerCurrentOrigin, [[self window] frame].size.width, partnerCurrentSize); + } else { + resizeRect = NSMakeRect(partnerCurrentOrigin, [[self window] frame].origin.y, partnerCurrentSize, [[self window] frame].size.height); + } + [[self window] setFrame:resizeRect display:YES]; + [self setFrame:myNewFrame]; + } + + // next + _currentStep++; + if (_currentStep == kPSMHideAnimationSteps + 1) { + _currentStep = kPSMIsNotBeingResized; + [self viewDidEndLiveResize]; + [self update:NO]; + + //send the delegate messages + if (_isHidden) { + if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { + [[self delegate] tabView:[self tabView] tabBarDidHide:self]; + } + } else { + [self addSubview:_overflowPopUpButton]; + [self addSubview:_addTabButton]; + + if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidUnhide:)]) { + [[self delegate] tabView:[self tabView] tabBarDidUnhide:self]; + } + } + + [_showHideAnimationTimer invalidate]; + _showHideAnimationTimer = nil; + } + [[self window] display]; +} + +- (BOOL)isTabBarHidden +{ + return _isHidden; +} + +- (BOOL)isAnimating +{ + return _animationTimer != nil; +} + +- (id)partnerView +{ + return partnerView; +} + +- (void)setPartnerView:(id)view +{ + partnerView = view; } #pragma mark - #pragma mark Drawing -- (BOOL)isFlipped { - return YES; -} - -- (void)drawRect:(NSRect)rect { - [style drawTabBar:self inRect:rect]; -} - -- (void)update { - [self update:_automaticallyAnimates]; -} - -- (void)update:(BOOL)animate { - // make sure all of our tabs are accounted for before updating - if((NSUInteger)[[self tabView] numberOfTabViewItems] != [_cells count]) { - return; - } - - // hide/show? (these return if already in desired state) - if((_hideForSingleTab) && ([_cells count] <= 1)) { - [self hideTabBar:YES animate:YES]; - return; - } else { - [self hideTabBar:NO animate:YES]; - } - - [self removeAllToolTips]; - [_controller layoutCells]; //eventually we should only have to call this when we know something has changed - - PSMTabBarCell *currentCell; - - NSMenu *overflowMenu = [_controller overflowMenu]; - [_overflowPopUpButton setHidden:(overflowMenu == nil)]; - [_overflowPopUpButton setMenu:overflowMenu]; - - [_animationTimer invalidate]; - _animationTimer = nil; - - if(animate) { - NSMutableArray *targetFrames = [NSMutableArray arrayWithCapacity:[_cells count]]; - - for(NSUInteger i = 0; i < [_cells count]; i++) { - currentCell = [_cells objectAtIndex:i]; - - //we're going from NSRect -> NSValue -> NSRect -> NSValue here - oh well - [targetFrames addObject:[NSValue valueWithRect:[_controller cellFrameAtIndex:i]]]; - } - - [_addTabButton setHidden:!_showAddTabButton]; - - NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.50 animationCurve:NSAnimationEaseInOut]; - [animation setAnimationBlockingMode:NSAnimationNonblocking]; - [animation startAnimation]; - _animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 - target:self - selector:@selector(_animateCells:) - userInfo:[NSArray arrayWithObjects:targetFrames, animation, nil] - repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; - [self _animateCells:_animationTimer]; - } else { - for(NSUInteger i = 0; i < [_cells count]; i++) { - currentCell = [_cells objectAtIndex:i]; - [currentCell setFrame:[_controller cellFrameAtIndex:i]]; - - if(![currentCell isInOverflowMenu]) { - [self _setupTrackingRectsForCell:currentCell]; - } - } - - [_addTabButton setFrame:[_controller addButtonRect]]; - [_addTabButton setHidden:!_showAddTabButton]; - [self setNeedsDisplay:YES]; - } -} - -- (void)_animateCells:(NSTimer *)timer { - NSAnimation *animation = [[timer userInfo] objectAtIndex:1]; - NSArray *targetFrames = [[timer userInfo] objectAtIndex:0]; - PSMTabBarCell *currentCell; - NSUInteger cellCount = [_cells count]; - - if((cellCount > 0) && [animation isAnimating]) { - //compare our target position with the current position and move towards the target - for(NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { - currentCell = [_cells objectAtIndex:i]; - NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; - CGFloat sizeChange; - CGFloat originChange; - - if([self orientation] == PSMTabBarHorizontalOrientation) { - sizeChange = (targetFrame.size.width - cellFrame.size.width) * [animation currentProgress]; - originChange = (targetFrame.origin.x - cellFrame.origin.x) * [animation currentProgress]; - cellFrame.size.width += sizeChange; - cellFrame.origin.x += originChange; - } else { - sizeChange = (targetFrame.size.height - cellFrame.size.height) * [animation currentProgress]; - originChange = (targetFrame.origin.y - cellFrame.origin.y) * [animation currentProgress]; - cellFrame.size.height += sizeChange; - cellFrame.origin.y += originChange; - } - - [currentCell setFrame:cellFrame]; - - //highlight the cell if the mouse is over it - NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; - NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; - [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; - [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; - } - - if(_showAddTabButton) { - //animate the add tab button - NSRect target = [_controller addButtonRect], frame = [_addTabButton frame]; - frame.origin.x += (target.origin.x - frame.origin.x) * [animation currentProgress]; - [_addTabButton setFrame:frame]; - } - } else { - //put all the cells where they should be in their final position - if(cellCount > 0) { - for(NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { - PSMTabBarCell *currentCell = [_cells objectAtIndex:i]; - NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; - - if([self orientation] == PSMTabBarHorizontalOrientation) { - cellFrame.size.width = targetFrame.size.width; - cellFrame.origin.x = targetFrame.origin.x; - } else { - cellFrame.size.height = targetFrame.size.height; - cellFrame.origin.y = targetFrame.origin.y; - } - - [currentCell setFrame:cellFrame]; - - //highlight the cell if the mouse is over it - NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; - NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; - [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; - [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; - } - } - - //set the frame for the add tab button - if(_showAddTabButton) { - NSRect frame = [_addTabButton frame]; - frame.origin.x = [_controller addButtonRect].origin.x; - [_addTabButton setFrame:frame]; - } - - [_animationTimer invalidate]; - _animationTimer = nil; - - for(NSUInteger i = 0; i < cellCount; i++) { - currentCell = [_cells objectAtIndex:i]; - - //we've hit the cells that are in overflow, stop setting up tracking rects - if([currentCell isInOverflowMenu]) { - break; - } - - [self _setupTrackingRectsForCell:currentCell]; - } - } - - [self setNeedsDisplay:YES]; -} - -- (void)_setupTrackingRectsForCell:(PSMTabBarCell *)cell { - NSInteger tag, index = [_cells indexOfObject:cell]; - NSRect cellTrackingRect = [_controller cellTrackingRectAtIndex:index]; - NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; - BOOL mouseInCell = NSMouseInRect(mousePoint, cellTrackingRect, [self isFlipped]); - - //set the cell tracking rect - [self removeTrackingRect:[cell cellTrackingTag]]; - tag = [self addTrackingRect:cellTrackingRect owner:cell userData:nil assumeInside:mouseInCell]; - [cell setCellTrackingTag:tag]; - [cell setHighlighted:mouseInCell]; - - if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSRect closeRect = [_controller closeButtonTrackingRectAtIndex:index]; - BOOL mouseInCloseRect = NSMouseInRect(mousePoint, closeRect, [self isFlipped]); - - //set the close button tracking rect - [self removeTrackingRect:[cell closeButtonTrackingTag]]; - tag = [self addTrackingRect:closeRect owner:cell userData:nil assumeInside:mouseInCloseRect]; - [cell setCloseButtonTrackingTag:tag]; - - [cell setCloseButtonOver:mouseInCloseRect]; - } - - //set the tooltip tracking rect - [self addToolTipRect:[cell frame] owner:self userData:nil]; -} - -- (void)_positionOverflowMenu { - NSRect cellRect, frame = [self frame]; - cellRect.size.height = [style tabCellHeight]; - cellRect.size.width = [style rightMarginForTabBarControl]; - - if([self orientation] == PSMTabBarHorizontalOrientation) { - cellRect.origin.y = 0; - cellRect.origin.x = frame.size.width - [style rightMarginForTabBarControl] + (_resizeAreaCompensation ? -(_resizeAreaCompensation - 1) : 1); - [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; - } else { - cellRect.origin.x = 0; - cellRect.origin.y = frame.size.height - [style tabCellHeight]; - cellRect.size.width = frame.size.width; - [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin | NSViewMinYMargin]; - } - - [_overflowPopUpButton setFrame:cellRect]; -} - -- (void)_checkWindowFrame { - //figure out if the new frame puts the control in the way of the resize widget - NSWindow *window = [self window]; - - if(window) { - NSRect resizeWidgetFrame = [[window contentView] frame]; - resizeWidgetFrame.origin.x += resizeWidgetFrame.size.width - 22; - resizeWidgetFrame.size.width = 22; - resizeWidgetFrame.size.height = 22; - - if([window showsResizeIndicator] && NSIntersectsRect([self frame], resizeWidgetFrame)) { - //the resize widgets are larger on metal windows - _resizeAreaCompensation = [window styleMask] & NSWindowStyleMaskTexturedBackground ? 20 : 8; - } else { - _resizeAreaCompensation = 0; - } +- (BOOL)isFlipped +{ + return YES; +} + +- (void)drawRect:(NSRect)rect +{ + [style drawTabBar:self inRect:rect]; +} + +- (void)update +{ + [self update:_automaticallyAnimates]; +} + +- (void)update:(BOOL)animate +{ + // make sure all of our tabs are accounted for before updating + if ((NSUInteger)[[self tabView] numberOfTabViewItems] != [_cells count]) { + return; + } + + // hide/show? (these return if already in desired state) + if ((_hideForSingleTab) && ([_cells count] <= 1)) { + [self hideTabBar:YES animate:YES]; + return; + } else { + [self hideTabBar:NO animate:YES]; + } + + [self removeAllToolTips]; + [_controller layoutCells]; //eventually we should only have to call this when we know something has changed + + PSMTabBarCell *currentCell; + + NSMenu *overflowMenu = [_controller overflowMenu]; + [_overflowPopUpButton setHidden:(overflowMenu == nil)]; + [_overflowPopUpButton setMenu:overflowMenu]; + + [_animationTimer invalidate]; + _animationTimer = nil; + + if (animate) { + NSMutableArray *targetFrames = [NSMutableArray arrayWithCapacity:[_cells count]]; + + for (NSUInteger i = 0; i < [_cells count]; i++) { + currentCell = [_cells objectAtIndex:i]; + + //we're going from NSRect -> NSValue -> NSRect -> NSValue here - oh well + [targetFrames addObject:[NSValue valueWithRect:[_controller cellFrameAtIndex:i]]]; + } + + [_addTabButton setHidden:!_showAddTabButton]; + + NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.50 animationCurve:NSAnimationEaseInOut]; + [animation setAnimationBlockingMode:NSAnimationNonblocking]; + [animation startAnimation]; + _animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 + target:self + selector:@selector(_animateCells:) + userInfo:[NSArray arrayWithObjects:targetFrames, animation, nil] + repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:_animationTimer forMode:NSEventTrackingRunLoopMode]; + [self _animateCells:_animationTimer]; + } else { + for (NSUInteger i = 0; i < [_cells count]; i++) { + currentCell = [_cells objectAtIndex:i]; + [currentCell setFrame:[_controller cellFrameAtIndex:i]]; + + if (![currentCell isInOverflowMenu]) { + [self _setupTrackingRectsForCell:currentCell]; + } + } + + [_addTabButton setFrame:[_controller addButtonRect]]; + [_addTabButton setHidden:!_showAddTabButton]; + [self setNeedsDisplay:YES]; + } +} + +- (void)_animateCells:(NSTimer *)timer +{ + NSAnimation *animation = [[timer userInfo] objectAtIndex:1]; + NSArray *targetFrames = [[timer userInfo] objectAtIndex:0]; + PSMTabBarCell *currentCell; + NSUInteger cellCount = [_cells count]; + + if ((cellCount > 0) && [animation isAnimating]) { + //compare our target position with the current position and move towards the target + for (NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { + currentCell = [_cells objectAtIndex:i]; + NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; + CGFloat sizeChange; + CGFloat originChange; + + if ([self orientation] == PSMTabBarHorizontalOrientation) { + sizeChange = (targetFrame.size.width - cellFrame.size.width) * [animation currentProgress]; + originChange = (targetFrame.origin.x - cellFrame.origin.x) * [animation currentProgress]; + cellFrame.size.width += sizeChange; + cellFrame.origin.x += originChange; + } else { + sizeChange = (targetFrame.size.height - cellFrame.size.height) * [animation currentProgress]; + originChange = (targetFrame.origin.y - cellFrame.origin.y) * [animation currentProgress]; + cellFrame.size.height += sizeChange; + cellFrame.origin.y += originChange; + } + + [currentCell setFrame:cellFrame]; + + //highlight the cell if the mouse is over it + NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; + NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; + [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; + [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; + } + + if (_showAddTabButton) { + //animate the add tab button + NSRect target = [_controller addButtonRect], frame = [_addTabButton frame]; + frame.origin.x += (target.origin.x - frame.origin.x) * [animation currentProgress]; + [_addTabButton setFrame:frame]; + } + } else { + //put all the cells where they should be in their final position + if (cellCount > 0) { + for (NSUInteger i = 0; i < [targetFrames count] && i < cellCount; i++) { + PSMTabBarCell *currentCell = [_cells objectAtIndex:i]; + NSRect cellFrame = [currentCell frame], targetFrame = [[targetFrames objectAtIndex:i] rectValue]; + + if ([self orientation] == PSMTabBarHorizontalOrientation) { + cellFrame.size.width = targetFrame.size.width; + cellFrame.origin.x = targetFrame.origin.x; + } else { + cellFrame.size.height = targetFrame.size.height; + cellFrame.origin.y = targetFrame.origin.y; + } + + [currentCell setFrame:cellFrame]; + + //highlight the cell if the mouse is over it + NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; + NSRect closeRect = [currentCell closeButtonRectForFrame:cellFrame]; + [currentCell setHighlighted:NSMouseInRect(mousePoint, cellFrame, [self isFlipped])]; + [currentCell setCloseButtonOver:NSMouseInRect(mousePoint, closeRect, [self isFlipped])]; + } + } + + //set the frame for the add tab button + if (_showAddTabButton) { + NSRect frame = [_addTabButton frame]; + frame.origin.x = [_controller addButtonRect].origin.x; + [_addTabButton setFrame:frame]; + } + + [_animationTimer invalidate]; + _animationTimer = nil; + + for (NSUInteger i = 0; i < cellCount; i++) { + currentCell = [_cells objectAtIndex:i]; + + //we've hit the cells that are in overflow, stop setting up tracking rects + if ([currentCell isInOverflowMenu]) { + break; + } + + [self _setupTrackingRectsForCell:currentCell]; + } + } + + [self setNeedsDisplay:YES]; +} + +- (void)_setupTrackingRectsForCell:(PSMTabBarCell *)cell +{ + NSInteger tag, index = [_cells indexOfObject:cell]; + NSRect cellTrackingRect = [_controller cellTrackingRectAtIndex:index]; + NSPoint mousePoint = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil]; + BOOL mouseInCell = NSMouseInRect(mousePoint, cellTrackingRect, [self isFlipped]); + + //set the cell tracking rect + [self removeTrackingRect:[cell cellTrackingTag]]; + tag = [self addTrackingRect:cellTrackingRect owner:cell userData:nil assumeInside:mouseInCell]; + [cell setCellTrackingTag:tag]; + [cell setHighlighted:mouseInCell]; + + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSRect closeRect = [_controller closeButtonTrackingRectAtIndex:index]; + BOOL mouseInCloseRect = NSMouseInRect(mousePoint, closeRect, [self isFlipped]); + + //set the close button tracking rect + [self removeTrackingRect:[cell closeButtonTrackingTag]]; + tag = [self addTrackingRect:closeRect owner:cell userData:nil assumeInside:mouseInCloseRect]; + [cell setCloseButtonTrackingTag:tag]; + + [cell setCloseButtonOver:mouseInCloseRect]; + } + + //set the tooltip tracking rect + [self addToolTipRect:[cell frame] owner:self userData:nil]; +} + +- (void)_positionOverflowMenu +{ + NSRect cellRect, frame = [self frame]; + cellRect.size.height = [style tabCellHeight]; + cellRect.size.width = [style rightMarginForTabBarControl]; + + if ([self orientation] == PSMTabBarHorizontalOrientation) { + cellRect.origin.y = 0; + cellRect.origin.x = frame.size.width - [style rightMarginForTabBarControl] + (_resizeAreaCompensation ? -(_resizeAreaCompensation - 1) : 1); + [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin]; + } else { + cellRect.origin.x = 0; + cellRect.origin.y = frame.size.height - [style tabCellHeight]; + cellRect.size.width = frame.size.width; + [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable | NSViewMinXMargin | NSViewMinYMargin]; + } + + [_overflowPopUpButton setFrame:cellRect]; +} + +- (void)_checkWindowFrame +{ + //figure out if the new frame puts the control in the way of the resize widget + NSWindow *window = [self window]; + + if (window) { + NSRect resizeWidgetFrame = [[window contentView] frame]; + resizeWidgetFrame.origin.x += resizeWidgetFrame.size.width - 22; + resizeWidgetFrame.size.width = 22; + resizeWidgetFrame.size.height = 22; - [self _positionOverflowMenu]; - } + if ([window showsResizeIndicator] && NSIntersectsRect([self frame], resizeWidgetFrame)) { + //the resize widgets are larger on metal windows + _resizeAreaCompensation = [window styleMask] & NSWindowStyleMaskTexturedBackground ? 20 : 8; + } else { + _resizeAreaCompensation = 0; + } + + [self _positionOverflowMenu]; + } } #pragma mark - #pragma mark Mouse Tracking -- (BOOL)mouseDownCanMoveWindow { - return NO; -} - -- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { - return YES; -} - -- (void)mouseDown:(NSEvent *)theEvent { - _didDrag = NO; - - // keep for dragging - [self setLastMouseDownEvent:theEvent]; - // what cell? - NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - NSRect frame = [self frame]; - - if([self orientation] == PSMTabBarVerticalOrientation && [self allowsResizing] && partnerView && (mousePt.x > frame.size.width - 3)) { - _resizing = YES; - } - - NSRect cellFrame; - PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; - if(cell) { - BOOL overClose = NSMouseInRect(mousePt, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]); - if(overClose && - ![self disableTabClose] && - ![cell isCloseButtonSuppressed] && - ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]] || [theEvent modifierFlags] & NSEventModifierFlagCommand)) { - [cell setCloseButtonOver:NO]; - [cell setCloseButtonPressed:YES]; - _closeClicked = YES; - } else { - [cell setCloseButtonPressed:NO]; - if(_selectsTabsOnMouseDown) { - [self performSelector:@selector(tabClick:) withObject:cell]; - } - } - [self setNeedsDisplay:YES]; - } -} - -- (void)mouseDragged:(NSEvent *)theEvent { - if([self lastMouseDownEvent] == nil) { - return; - } - - NSPoint currentPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - - if(_resizing) { - NSRect frame = [self frame]; - CGFloat resizeAmount = [theEvent deltaX]; - if((currentPoint.x > frame.size.width && resizeAmount > 0) || (currentPoint.x < frame.size.width && resizeAmount < 0)) { - [[NSCursor resizeLeftRightCursor] push]; - - NSRect partnerFrame = [partnerView frame]; - - //do some bounds checking - if((frame.size.width + resizeAmount > [self cellMinWidth]) && (frame.size.width + resizeAmount < [self cellMaxWidth])) { - frame.size.width += resizeAmount; - partnerFrame.size.width -= resizeAmount; - partnerFrame.origin.x += resizeAmount; - - [self setFrame:frame]; - [partnerView setFrame:partnerFrame]; - [[self superview] setNeedsDisplay:YES]; - } - } - return; - } - - NSRect cellFrame; - NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; - PSMTabBarCell *cell = [self cellForPoint:trackingStartPoint cellFrame:&cellFrame]; - if(cell) { - //check to see if the close button was the target in the clicked cell - //highlight/unhighlight the close button as necessary - NSRect iconRect = [cell closeButtonRectForFrame:cellFrame]; - - if(_closeClicked && NSMouseInRect(trackingStartPoint, iconRect, [self isFlipped]) && - ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]])) { - [cell setCloseButtonPressed:NSMouseInRect(currentPoint, iconRect, [self isFlipped])]; - [self setNeedsDisplay:YES]; - return; - } - - CGFloat dx = fabs(currentPoint.x - trackingStartPoint.x); - CGFloat dy = fabs(currentPoint.y - trackingStartPoint.y); - CGFloat distance = sqrt(dx * dx + dy * dy); - - if(distance >= 10 && !_didDrag && ![[PSMTabDragAssistant sharedDragAssistant] isDragging] && - [self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDragTabViewItem:fromTabBar:)] && - [[self delegate] tabView:tabView shouldDragTabViewItem:[cell representedObject] fromTabBar:self]) { - _didDrag = YES; - [[PSMTabDragAssistant sharedDragAssistant] startDraggingCell:cell fromTabBar:self withMouseDownEvent:[self lastMouseDownEvent]]; - } - } -} - -- (void)mouseUp:(NSEvent *)theEvent { - if(_resizing) { - _resizing = NO; - [[NSCursor arrowCursor] set]; - } else { - // what cell? - NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - NSRect cellFrame, mouseDownCellFrame; - PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; - PSMTabBarCell *mouseDownCell = [self cellForPoint:[self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil] cellFrame:&mouseDownCellFrame]; - if(cell) { - NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; - NSRect iconRect = [mouseDownCell closeButtonRectForFrame:mouseDownCellFrame]; - - if((NSMouseInRect(mousePt, iconRect, [self isFlipped])) && ![self disableTabClose] && ![cell isCloseButtonSuppressed] && [mouseDownCell closeButtonPressed]) { - if(([[NSApp currentEvent] modifierFlags] & NSEventModifierFlagOption) != 0) { - //If the user is holding Option, close all other tabs - NSEnumerator *enumerator = [[[self cells] copy] objectEnumerator]; - PSMTabBarCell *otherCell; - - while((otherCell = [enumerator nextObject])) { - if(otherCell != cell) { - [self performSelector:@selector(closeTabClick:) withObject:otherCell]; - } - } - - //Fix the close button for the clicked tab not to be pressed - [cell setCloseButtonPressed:NO]; - } else { - //Otherwise, close this tab - [self performSelector:@selector(closeTabClick:) withObject:cell]; - } - } else if(NSMouseInRect(mousePt, mouseDownCellFrame, [self isFlipped]) && - (!NSMouseInRect(trackingStartPoint, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]) || ![self allowsBackgroundTabClosing] || [self disableTabClose])) { - [mouseDownCell setCloseButtonPressed:NO]; - // If -[self selectsTabsOnMouseDown] is TRUE, we already performed tabClick: on mouseDown. - if(![self selectsTabsOnMouseDown]) { - [self performSelector:@selector(tabClick:) withObject:cell]; - } - } else { - [mouseDownCell setCloseButtonPressed:NO]; - [self performSelector:@selector(tabNothing:) withObject:cell]; - } - } - - _closeClicked = NO; - } -} - -- (NSMenu *)menuForEvent:(NSEvent *)event { - NSMenu *menu = nil; - NSTabViewItem *item = [[self cellForPoint:[self convertPoint:[event locationInWindow] fromView:nil] cellFrame:nil] representedObject]; - - if(item && [[self delegate] respondsToSelector:@selector(tabView:menuForTabViewItem:)]) { - menu = [[self delegate] tabView:tabView menuForTabViewItem:item]; - } - return menu; +- (BOOL)mouseDownCanMoveWindow +{ + return NO; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + return YES; +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + _didDrag = NO; + + // keep for dragging + [self setLastMouseDownEvent:theEvent]; + // what cell? + NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect frame = [self frame]; + + if ([self orientation] == PSMTabBarVerticalOrientation && [self allowsResizing] && partnerView && (mousePt.x > frame.size.width - 3)) { + _resizing = YES; + } + + NSRect cellFrame; + PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; + if (cell) { + BOOL overClose = NSMouseInRect(mousePt, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]); + if (overClose && ![self disableTabClose] && ![cell isCloseButtonSuppressed] && ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]] || [theEvent modifierFlags] & NSEventModifierFlagCommand)) { + [cell setCloseButtonOver:NO]; + [cell setCloseButtonPressed:YES]; + _closeClicked = YES; + } else { + [cell setCloseButtonPressed:NO]; + if (_selectsTabsOnMouseDown) { + [self performSelector:@selector(tabClick:) withObject:cell]; + } + } + [self setNeedsDisplay:YES]; + } +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + if ([self lastMouseDownEvent] == nil) { + return; + } + + NSPoint currentPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + + if (_resizing) { + NSRect frame = [self frame]; + CGFloat resizeAmount = [theEvent deltaX]; + if ((currentPoint.x > frame.size.width && resizeAmount > 0) || (currentPoint.x < frame.size.width && resizeAmount < 0)) { + [[NSCursor resizeLeftRightCursor] push]; + + NSRect partnerFrame = [partnerView frame]; + + //do some bounds checking + if ((frame.size.width + resizeAmount > [self cellMinWidth]) && (frame.size.width + resizeAmount < [self cellMaxWidth])) { + frame.size.width += resizeAmount; + partnerFrame.size.width -= resizeAmount; + partnerFrame.origin.x += resizeAmount; + + [self setFrame:frame]; + [partnerView setFrame:partnerFrame]; + [[self superview] setNeedsDisplay:YES]; + } + } + return; + } + + NSRect cellFrame; + NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; + PSMTabBarCell *cell = [self cellForPoint:trackingStartPoint cellFrame:&cellFrame]; + if (cell) { + //check to see if the close button was the target in the clicked cell + //highlight/unhighlight the close button as necessary + NSRect iconRect = [cell closeButtonRectForFrame:cellFrame]; + + if (_closeClicked && NSMouseInRect(trackingStartPoint, iconRect, [self isFlipped]) && ([self allowsBackgroundTabClosing] || [[cell representedObject] isEqualTo:[tabView selectedTabViewItem]])) { + [cell setCloseButtonPressed:NSMouseInRect(currentPoint, iconRect, [self isFlipped])]; + [self setNeedsDisplay:YES]; + return; + } + + CGFloat dx = fabs(currentPoint.x - trackingStartPoint.x); + CGFloat dy = fabs(currentPoint.y - trackingStartPoint.y); + CGFloat distance = sqrt(dx * dx + dy * dy); + + if (distance >= 10 && !_didDrag && ![[PSMTabDragAssistant sharedDragAssistant] isDragging] && + [self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDragTabViewItem:fromTabBar:)] && + [[self delegate] tabView:tabView + shouldDragTabViewItem:[cell representedObject] + fromTabBar:self]) { + _didDrag = YES; + [[PSMTabDragAssistant sharedDragAssistant] startDraggingCell:cell fromTabBar:self withMouseDownEvent:[self lastMouseDownEvent]]; + } + } +} + +- (void)mouseUp:(NSEvent *)theEvent +{ + if (_resizing) { + _resizing = NO; + [[NSCursor arrowCursor] set]; + } else { + // what cell? + NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect cellFrame, mouseDownCellFrame; + PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; + PSMTabBarCell *mouseDownCell = [self cellForPoint:[self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil] cellFrame:&mouseDownCellFrame]; + if (cell) { + NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; + NSRect iconRect = [mouseDownCell closeButtonRectForFrame:mouseDownCellFrame]; + + if ((NSMouseInRect(mousePt, iconRect, [self isFlipped])) && ![self disableTabClose] && ![cell isCloseButtonSuppressed] && [mouseDownCell closeButtonPressed]) { + if (([[NSApp currentEvent] modifierFlags] & NSEventModifierFlagOption) != 0) { + //If the user is holding Option, close all other tabs + NSEnumerator *enumerator = [[[self cells] copy] objectEnumerator]; + PSMTabBarCell *otherCell; + + while ((otherCell = [enumerator nextObject])) { + if (otherCell != cell) { + [self performSelector:@selector(closeTabClick:) withObject:otherCell]; + } + } + + //Fix the close button for the clicked tab not to be pressed + [cell setCloseButtonPressed:NO]; + } else { + //Otherwise, close this tab + [self performSelector:@selector(closeTabClick:) withObject:cell]; + } + } else if (NSMouseInRect(mousePt, mouseDownCellFrame, [self isFlipped]) && (!NSMouseInRect(trackingStartPoint, [cell closeButtonRectForFrame:cellFrame], [self isFlipped]) || ![self allowsBackgroundTabClosing] || [self disableTabClose])) { + [mouseDownCell setCloseButtonPressed:NO]; + // If -[self selectsTabsOnMouseDown] is TRUE, we already performed tabClick: on mouseDown. + if (![self selectsTabsOnMouseDown]) { + [self performSelector:@selector(tabClick:) withObject:cell]; + } + } else { + [mouseDownCell setCloseButtonPressed:NO]; + [self performSelector:@selector(tabNothing:) withObject:cell]; + } + } + + _closeClicked = NO; + } +} + +- (NSMenu *)menuForEvent:(NSEvent *)event +{ + NSMenu *menu = nil; + NSTabViewItem *item = [[self cellForPoint:[self convertPoint:[event locationInWindow] fromView:nil] cellFrame:nil] representedObject]; + + if (item && [[self delegate] respondsToSelector:@selector(tabView:menuForTabViewItem:)]) { + menu = [[self delegate] tabView:tabView menuForTabViewItem:item]; + } + return menu; } #pragma mark - #pragma mark Drag and Drop -- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent { - return YES; +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent +{ + return YES; } // NSDraggingSource -- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { - return(isLocal ? NSDragOperationMove : NSDragOperationNone); +- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal +{ + return (isLocal ? NSDragOperationMove : NSDragOperationNone); } -- (BOOL)ignoreModifierKeysWhileDragging { - return YES; +- (BOOL)ignoreModifierKeysWhileDragging +{ + return YES; } -- (void)draggedImage:(NSImage *)anImage beganAt:(NSPoint)screenPoint { - [[PSMTabDragAssistant sharedDragAssistant] draggingBeganAt:screenPoint]; +- (void)draggedImage:(NSImage *)anImage beganAt:(NSPoint)screenPoint +{ + [[PSMTabDragAssistant sharedDragAssistant] draggingBeganAt:screenPoint]; } -- (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint { - [[PSMTabDragAssistant sharedDragAssistant] draggingMovedTo:screenPoint]; +- (void)draggedImage:(NSImage *)image movedTo:(NSPoint)screenPoint +{ + [[PSMTabDragAssistant sharedDragAssistant] draggingMovedTo:screenPoint]; } // NSDraggingDestination -- (NSDragOperation)draggingEntered:(id )sender { - if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { - if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { - return NSDragOperationNone; - } +- (NSDragOperation)draggingEntered:(id)sender +{ + if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { + return NSDragOperationNone; + } - [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; - return NSDragOperationMove; - } + [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } - return NSDragOperationNone; + return NSDragOperationNone; } -- (NSDragOperation)draggingUpdated:(id )sender { - PSMTabBarCell *cell = [self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil]; +- (NSDragOperation)draggingUpdated:(id)sender +{ + PSMTabBarCell *cell = [self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil]; - if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { - if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { - return NSDragOperationNone; - } + if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && ![[self delegate] tabView:[[sender draggingSource] tabView] shouldDropTabViewItem:[[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject] inTabBar:self]) { + return NSDragOperationNone; + } - [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; - return NSDragOperationMove; - } else if(cell) { - //something that was accepted by the delegate was dragged on + [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } else if (cell) { + //something that was accepted by the delegate was dragged on - //Test for the space bar (the skip-the-delay key). - /*enum { virtualKeycodeForSpace = 49 }; //Source: IM:Tx (Fig. C-2) + //Test for the space bar (the skip-the-delay key). + /*enum { virtualKeycodeForSpace = 49 }; //Source: IM:Tx (Fig. C-2) union { KeyMap keymap; char bits[16]; @@ -1314,609 +1394,642 @@ //For some reason, it crashes if I call -fire here. I don't know why. It doesn't crash if I simply set the fire date to now. [_springTimer setFireDate:[NSDate date]]; } else {*/ - //Wind the spring for a spring-loaded drop. - //The delay time comes from Finder's defaults, which specifies it in milliseconds. - //If the delegate can't handle our spring-loaded drop, we'll abort it when the timer fires. See fireSpring:. This is simpler than constantly (checking for spring-loaded awareness and tearing down/rebuilding the timer) at every delegate change. - - //If the user has dragged to a different tab, reset the timer. - if(_tabViewItemWithSpring != [cell representedObject]) { - [_springTimer invalidate]; - _springTimer = nil; - _tabViewItemWithSpring = [cell representedObject]; - } - if(!_springTimer) { - //Finder's default delay time, as of Tiger, is 668 ms. If the user has never changed it, there's no setting in its defaults, so we default to that amount. - NSNumber *delayNumber = (__bridge_transfer NSNumber *)CFPreferencesCopyAppValue((CFStringRef)@"SpringingDelayMilliseconds", (CFStringRef)@"com.apple.finder"); - NSTimeInterval delaySeconds = delayNumber ?[delayNumber doubleValue] / 1000.0 : 0.668; - _springTimer = [NSTimer scheduledTimerWithTimeInterval:delaySeconds - target:self - selector:@selector(fireSpring:) - userInfo:sender - repeats:NO]; - } - return NSDragOperationCopy; - } - - return NSDragOperationNone; -} - -- (void)draggingExited:(id )sender { - [_springTimer invalidate]; - _springTimer = nil; + //Wind the spring for a spring-loaded drop. + //The delay time comes from Finder's defaults, which specifies it in milliseconds. + //If the delegate can't handle our spring-loaded drop, we'll abort it when the timer fires. See fireSpring:. This is simpler than constantly (checking for spring-loaded awareness and tearing down/rebuilding the timer) at every delegate change. + + //If the user has dragged to a different tab, reset the timer. + if (_tabViewItemWithSpring != [cell representedObject]) { + [_springTimer invalidate]; + _springTimer = nil; + _tabViewItemWithSpring = [cell representedObject]; + } + if (!_springTimer) { + //Finder's default delay time, as of Tiger, is 668 ms. If the user has never changed it, there's no setting in its defaults, so we default to that amount. + NSNumber *delayNumber = (__bridge_transfer NSNumber *)CFPreferencesCopyAppValue((CFStringRef) @"SpringingDelayMilliseconds", (CFStringRef) @"com.apple.finder"); + NSTimeInterval delaySeconds = delayNumber ? [delayNumber doubleValue] / 1000.0 : 0.668; + _springTimer = [NSTimer scheduledTimerWithTimeInterval:delaySeconds + target:self + selector:@selector(fireSpring:) + userInfo:sender + repeats:NO]; + } + return NSDragOperationCopy; + } + + return NSDragOperationNone; +} + +- (void)draggingExited:(id)sender +{ + [_springTimer invalidate]; + _springTimer = nil; - [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; + [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; } -- (BOOL)prepareForDragOperation:(id )sender { - //validate the drag operation only if there's a valid tab bar to drop into - return [[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] == NSNotFound || - [[PSMTabDragAssistant sharedDragAssistant] destinationTabBar] != nil; +- (BOOL)prepareForDragOperation:(id)sender +{ + //validate the drag operation only if there's a valid tab bar to drop into + return [[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] == NSNotFound || + [[PSMTabDragAssistant sharedDragAssistant] destinationTabBar] != nil; } -- (BOOL)performDragOperation:(id )sender { - if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { - [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; - } else if([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:acceptedDraggingInfo:onTabViewItem:)]) { - //forward the drop to the delegate - [[self delegate] tabView:tabView acceptedDraggingInfo:sender onTabViewItem:[[self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil] representedObject]]; - } - return YES; +- (BOOL)performDragOperation:(id)sender +{ + if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; + } else if ([self delegate] && [[self delegate] respondsToSelector:@selector(tabView:acceptedDraggingInfo:onTabViewItem:)]) { + //forward the drop to the delegate + [[self delegate] tabView:tabView acceptedDraggingInfo:sender onTabViewItem:[[self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil] representedObject]]; + } + return YES; } -- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation { - [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; } -- (void)concludeDragOperation:(id )sender { +- (void)concludeDragOperation:(id)sender +{ } #pragma mark - #pragma mark Spring-loading -- (void)fireSpring:(NSTimer *)timer { - NSAssert1(timer == _springTimer, @"Spring fired by unrecognized timer %@", timer); +- (void)fireSpring:(NSTimer *)timer +{ + NSAssert1(timer == _springTimer, @"Spring fired by unrecognized timer %@", timer); - id sender = [timer userInfo]; - PSMTabBarCell *cell = [self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil]; - [tabView selectTabViewItem:[cell representedObject]]; + id sender = [timer userInfo]; + PSMTabBarCell *cell = [self cellForPoint:[self convertPoint:[sender draggingLocation] fromView:nil] cellFrame:nil]; + [tabView selectTabViewItem:[cell representedObject]]; - _tabViewItemWithSpring = nil; - [_springTimer invalidate]; - _springTimer = nil; + _tabViewItemWithSpring = nil; + [_springTimer invalidate]; + _springTimer = nil; } #pragma mark - #pragma mark Actions -- (void)overflowMenuAction:(id)sender { - NSTabViewItem *tabViewItem = (NSTabViewItem *)[sender representedObject]; - [tabView selectTabViewItem:tabViewItem]; +- (void)overflowMenuAction:(id)sender +{ + NSTabViewItem *tabViewItem = (NSTabViewItem *)[sender representedObject]; + [tabView selectTabViewItem:tabViewItem]; +} + +- (void)closeTabClick:(id)sender +{ + NSTabViewItem *item = [sender representedObject]; + if (([_cells count] == 1) && (![self canCloseOnlyTab])) { + return; + } + + if ([[self delegate] respondsToSelector:@selector(tabView:shouldCloseTabViewItem:)]) { + if (![[self delegate] tabView:tabView shouldCloseTabViewItem:item]) { + // fix mouse downed close button + [sender setCloseButtonPressed:NO]; + return; + } + } + + [tabView removeTabViewItem:item]; +} + +- (void)tabClick:(id)sender +{ + [tabView selectTabViewItem:[sender representedObject]]; +} + +- (void)tabNothing:(id)sender +{ + //[self update]; // takes care of highlighting based on state +} + +- (void)frameDidChange:(NSNotification *)notification +{ + [self _checkWindowFrame]; + + // trying to address the drawing artifacts for the progress indicators - hackery follows + // this one fixes the "blanking" effect when the control hides and shows itself + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + [[cell indicator] stopAnimation:self]; + + [[cell indicator] performSelector:@selector(startAnimation:) + withObject:nil + afterDelay:0]; + } + + [self update:NO]; } -- (void)closeTabClick:(id)sender { - NSTabViewItem *item = [sender representedObject]; - if(([_cells count] == 1) && (![self canCloseOnlyTab])) { - return; - } +- (void)viewDidMoveToWindow +{ + [self _checkWindowFrame]; +} + +- (void)viewWillStartLiveResize +{ + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + [[cell indicator] stopAnimation:self]; + } + [self setNeedsDisplay:YES]; +} + +- (void)viewDidEndLiveResize +{ + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + [[cell indicator] startAnimation:self]; + } - if([[self delegate] respondsToSelector:@selector(tabView:shouldCloseTabViewItem:)]) { - if(![[self delegate] tabView:tabView shouldCloseTabViewItem:item]) { - // fix mouse downed close button - [sender setCloseButtonPressed:NO]; - return; - } - } - - - [tabView removeTabViewItem:item]; -} - -- (void)tabClick:(id)sender { - [tabView selectTabViewItem:[sender representedObject]]; -} - -- (void)tabNothing:(id)sender { - //[self update]; // takes care of highlighting based on state -} - -- (void)frameDidChange:(NSNotification *)notification { - [self _checkWindowFrame]; - - // trying to address the drawing artifacts for the progress indicators - hackery follows - // this one fixes the "blanking" effect when the control hides and shows itself - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - [[cell indicator] stopAnimation:self]; - - [[cell indicator] performSelector:@selector(startAnimation:) - withObject:nil - afterDelay:0]; - } - - [self update:NO]; -} - -- (void)viewDidMoveToWindow { - [self _checkWindowFrame]; -} - -- (void)viewWillStartLiveResize { - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - [[cell indicator] stopAnimation:self]; - } - [self setNeedsDisplay:YES]; -} - --(void)viewDidEndLiveResize { - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - [[cell indicator] startAnimation:self]; - } - - [self _checkWindowFrame]; - [self update:NO]; -} - -- (void)resetCursorRects { - [super resetCursorRects]; - if([self orientation] == PSMTabBarVerticalOrientation) { - NSRect frame = [self frame]; - [self addCursorRect:NSMakeRect(frame.size.width - 2, 0, 2, frame.size.height) cursor:[NSCursor resizeLeftRightCursor]]; - } -} - -- (void)windowDidMove:(NSNotification *)aNotification { - [self setNeedsDisplay:YES]; -} - -- (void)windowDidUpdate:(NSNotification *)notification { - // hide? must readjust things if I'm not supposed to be showing - // this block of code only runs when the app launches - if([self hideForSingleTab] && ([_cells count] <= 1) && !_awakenedFromNib) { - // must adjust frames now before display - NSRect myFrame = [self frame]; - if([self orientation] == PSMTabBarHorizontalOrientation) { - if(partnerView) { - NSRect partnerFrame = [partnerView frame]; - // above or below me? - if(myFrame.origin.y - 22 > [partnerView frame].origin.y) { - // partner is below me - [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y + 21, myFrame.size.width, myFrame.size.height - 21)]; - [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width, partnerFrame.size.height + 21)]; - } else { - // partner is above me - [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; - [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y - 21, partnerFrame.size.width, partnerFrame.size.height + 21)]; - } - [partnerView setNeedsDisplay:YES]; - [self setNeedsDisplay:YES]; - } else { - // for window movement - NSRect windowFrame = [[self window] frame]; - [[self window] setFrame:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y + 21, windowFrame.size.width, windowFrame.size.height - 21) display:YES]; - [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; - } - } else { - if(partnerView) { - NSRect partnerFrame = [partnerView frame]; - //to the left or right? - if(myFrame.origin.x < [partnerView frame].origin.x) { - // partner is to the left - [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; - [partnerView setFrame:NSMakeRect(partnerFrame.origin.x - myFrame.size.width + 1, partnerFrame.origin.y, partnerFrame.size.width + myFrame.size.width - 1, partnerFrame.size.height)]; - } else { - // partner to the right - [self setFrame:NSMakeRect(myFrame.origin.x + myFrame.size.width, myFrame.origin.y, 1, myFrame.size.height)]; - [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width + myFrame.size.width, partnerFrame.size.height)]; - } - _tabBarWidth = myFrame.size.width; - [partnerView setNeedsDisplay:YES]; - [self setNeedsDisplay:YES]; - } else { - // for window movement - NSRect windowFrame = [[self window] frame]; - [[self window] setFrame:NSMakeRect(windowFrame.origin.x + myFrame.size.width - 1, windowFrame.origin.y, windowFrame.size.width - myFrame.size.width + 1, windowFrame.size.height) display:YES]; - [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; - } - } - - _isHidden = YES; - - if([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { - [[self delegate] tabView:[self tabView] tabBarDidHide:self]; - } - } - - _awakenedFromNib = YES; - [self setNeedsDisplay:YES]; - - //we only need to do this once - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidUpdateNotification object:nil]; + [self _checkWindowFrame]; + [self update:NO]; +} + +- (void)resetCursorRects +{ + [super resetCursorRects]; + if ([self orientation] == PSMTabBarVerticalOrientation) { + NSRect frame = [self frame]; + [self addCursorRect:NSMakeRect(frame.size.width - 2, 0, 2, frame.size.height) cursor:[NSCursor resizeLeftRightCursor]]; + } +} + +- (void)windowDidMove:(NSNotification *)aNotification +{ + [self setNeedsDisplay:YES]; +} + +- (void)windowDidUpdate:(NSNotification *)notification +{ + // hide? must readjust things if I'm not supposed to be showing + // this block of code only runs when the app launches + if ([self hideForSingleTab] && ([_cells count] <= 1) && !_awakenedFromNib) { + // must adjust frames now before display + NSRect myFrame = [self frame]; + if ([self orientation] == PSMTabBarHorizontalOrientation) { + if (partnerView) { + NSRect partnerFrame = [partnerView frame]; + // above or below me? + if (myFrame.origin.y - 22 > [partnerView frame].origin.y) { + // partner is below me + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y + 21, myFrame.size.width, myFrame.size.height - 21)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width, partnerFrame.size.height + 21)]; + } else { + // partner is above me + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y - 21, partnerFrame.size.width, partnerFrame.size.height + 21)]; + } + [partnerView setNeedsDisplay:YES]; + [self setNeedsDisplay:YES]; + } else { + // for window movement + NSRect windowFrame = [[self window] frame]; + [[self window] setFrame:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y + 21, windowFrame.size.width, windowFrame.size.height - 21) display:YES]; + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; + } + } else { + if (partnerView) { + NSRect partnerFrame = [partnerView frame]; + //to the left or right? + if (myFrame.origin.x < [partnerView frame].origin.x) { + // partner is to the left + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x - myFrame.size.width + 1, partnerFrame.origin.y, partnerFrame.size.width + myFrame.size.width - 1, partnerFrame.size.height)]; + } else { + // partner to the right + [self setFrame:NSMakeRect(myFrame.origin.x + myFrame.size.width, myFrame.origin.y, 1, myFrame.size.height)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width + myFrame.size.width, partnerFrame.size.height)]; + } + _tabBarWidth = myFrame.size.width; + [partnerView setNeedsDisplay:YES]; + [self setNeedsDisplay:YES]; + } else { + // for window movement + NSRect windowFrame = [[self window] frame]; + [[self window] setFrame:NSMakeRect(windowFrame.origin.x + myFrame.size.width - 1, windowFrame.origin.y, windowFrame.size.width - myFrame.size.width + 1, windowFrame.size.height) display:YES]; + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, 1, myFrame.size.height)]; + } + } + + _isHidden = YES; + + if ([[self delegate] respondsToSelector:@selector(tabView:tabBarDidHide:)]) { + [[self delegate] tabView:[self tabView] tabBarDidHide:self]; + } + } + + _awakenedFromNib = YES; + [self setNeedsDisplay:YES]; + + //we only need to do this once + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidUpdateNotification object:nil]; } #pragma mark - #pragma mark Menu Validation -- (BOOL)validateMenuItem:(NSMenuItem *)sender { - [sender setState:([[sender representedObject] isEqualTo:[tabView selectedTabViewItem]]) ? NSOnState : NSOffState]; +- (BOOL)validateMenuItem:(NSMenuItem *)sender +{ + [sender setState:([[sender representedObject] isEqualTo:[tabView selectedTabViewItem]]) ? NSOnState : NSOffState]; - return [[self delegate] respondsToSelector:@selector(tabView:validateOverflowMenuItem:forTabViewItem:)] ? - [[self delegate] tabView:[self tabView] validateOverflowMenuItem:sender forTabViewItem:[sender representedObject]] : YES; + return [[self delegate] respondsToSelector:@selector(tabView:validateOverflowMenuItem:forTabViewItem:)] ? [[self delegate] tabView:[self tabView] validateOverflowMenuItem:sender forTabViewItem:[sender representedObject]] : YES; } #pragma mark - #pragma mark NSTabView Delegate -- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { - // here's a weird one - this message is sent before the "tabViewDidChangeNumberOfTabViewItems" - // message, thus I can end up updating when there are no cells, if no tabs were (yet) present - NSUInteger tabIndex = [aTabView indexOfTabViewItem:tabViewItem]; - - if([_cells count] > 0 && tabIndex < [_cells count]) { - PSMTabBarCell *thisCell = [_cells objectAtIndex:tabIndex]; - if(_alwaysShowActiveTab && [thisCell isInOverflowMenu]) { - //temporarily disable the delegate in order to move the tab to a different index - id tempDelegate = [aTabView delegate]; - [aTabView setDelegate:nil]; - - // move it all around first - [aTabView removeTabViewItem:tabViewItem]; - [aTabView insertTabViewItem:tabViewItem atIndex:0]; - [_cells removeObjectAtIndex:tabIndex]; - [_cells insertObject:thisCell atIndex:0]; - [thisCell setIsInOverflowMenu:NO]; //very important else we get a fun recursive loop going - [[_cells objectAtIndex:[_cells count] - 1] setIsInOverflowMenu:YES]; //these 2 lines are pretty uncool and this logic needs to be updated - - [aTabView setDelegate:tempDelegate]; - - //reset the selection since removing it changed the selection - [aTabView selectTabViewItem:tabViewItem]; - - [self update]; - } else { - [_controller setSelectedCell:thisCell]; - [self setNeedsDisplay:YES]; - } - } - - if([[self delegate] respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { - [[self delegate] performSelector:@selector(tabView:didSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; - } -} - -- (BOOL)tabView:(NSTabView *)aTabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem { - if([[self delegate] respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { - return [[self delegate] tabView:aTabView shouldSelectTabViewItem:tabViewItem]; - } else { - return YES; - } -} -- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem { - if([[self delegate] respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { - [[self delegate] performSelector:@selector(tabView:willSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; - } -} - -- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView { - NSArray *tabItems = [tabView tabViewItems]; - // go through cells, remove any whose representedObjects are not in [tabView tabViewItems] - NSEnumerator *e = [[_cells copy] objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - //remove the observer binding - if([cell representedObject] && ![tabItems containsObject:[cell representedObject]]) { - if([[self delegate] respondsToSelector:@selector(tabView:didCloseTabViewItem:)]) { - [[self delegate] tabView:aTabView didCloseTabViewItem:[cell representedObject]]; - } - - [self removeTabForCell:cell]; - } - } - - // go through tab view items, add cell for any not present - NSMutableArray *cellItems = [self representedTabViewItems]; - NSEnumerator *ex = [tabItems objectEnumerator]; - NSTabViewItem *item; - while((item = [ex nextObject])) { - if(![cellItems containsObject:item]) { - [self addTabViewItem:item]; - } - } - - // pass along for other delegate responses - if([[self delegate] respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]) { - [[self delegate] performSelector:@selector(tabViewDidChangeNumberOfTabViewItems:) withObject:aTabView]; - } - - // reset cursor tracking for the add tab button if one exists - if([self addTabButton]) { - [[self addTabButton] resetCursorRects]; - } +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + // here's a weird one - this message is sent before the "tabViewDidChangeNumberOfTabViewItems" + // message, thus I can end up updating when there are no cells, if no tabs were (yet) present + NSUInteger tabIndex = [aTabView indexOfTabViewItem:tabViewItem]; + + if ([_cells count] > 0 && tabIndex < [_cells count]) { + PSMTabBarCell *thisCell = [_cells objectAtIndex:tabIndex]; + if (_alwaysShowActiveTab && [thisCell isInOverflowMenu]) { + //temporarily disable the delegate in order to move the tab to a different index + id tempDelegate = [aTabView delegate]; + [aTabView setDelegate:nil]; + + // move it all around first + [aTabView removeTabViewItem:tabViewItem]; + [aTabView insertTabViewItem:tabViewItem atIndex:0]; + [_cells removeObjectAtIndex:tabIndex]; + [_cells insertObject:thisCell atIndex:0]; + [thisCell setIsInOverflowMenu:NO]; //very important else we get a fun recursive loop going + [[_cells objectAtIndex:[_cells count] - 1] setIsInOverflowMenu:YES]; //these 2 lines are pretty uncool and this logic needs to be updated + + [aTabView setDelegate:tempDelegate]; + + //reset the selection since removing it changed the selection + [aTabView selectTabViewItem:tabViewItem]; + + [self update]; + } else { + [_controller setSelectedCell:thisCell]; + [self setNeedsDisplay:YES]; + } + } + + if ([[self delegate] respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { + [[self delegate] performSelector:@selector(tabView:didSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; + } +} + +- (BOOL)tabView:(NSTabView *)aTabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if ([[self delegate] respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { + return [[self delegate] tabView:aTabView shouldSelectTabViewItem:tabViewItem]; + } else { + return YES; + } +} +- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if ([[self delegate] respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { + [[self delegate] performSelector:@selector(tabView:willSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; + } +} + +- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView +{ + NSArray *tabItems = [tabView tabViewItems]; + // go through cells, remove any whose representedObjects are not in [tabView tabViewItems] + NSEnumerator *e = [[_cells copy] objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + //remove the observer binding + if ([cell representedObject] && ![tabItems containsObject:[cell representedObject]]) { + if ([[self delegate] respondsToSelector:@selector(tabView:didCloseTabViewItem:)]) { + [[self delegate] tabView:aTabView didCloseTabViewItem:[cell representedObject]]; + } + + [self removeTabForCell:cell]; + } + } + + // go through tab view items, add cell for any not present + NSMutableArray *cellItems = [self representedTabViewItems]; + NSEnumerator *ex = [tabItems objectEnumerator]; + NSTabViewItem *item; + while ((item = [ex nextObject])) { + if (![cellItems containsObject:item]) { + [self addTabViewItem:item]; + } + } + + // pass along for other delegate responses + if ([[self delegate] respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]) { + [[self delegate] performSelector:@selector(tabViewDidChangeNumberOfTabViewItems:) withObject:aTabView]; + } + + // reset cursor tracking for the add tab button if one exists + if ([self addTabButton]) { + [[self addTabButton] resetCursorRects]; + } } #pragma mark - #pragma mark Tooltips -- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)userData { - if([[self delegate] respondsToSelector:@selector(tabView:toolTipForTabViewItem:)]) { - return [[self delegate] tabView:[self tabView] toolTipForTabViewItem:[[self cellForPoint:point cellFrame:nil] representedObject]]; - } - return nil; +- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)userData +{ + if ([[self delegate] respondsToSelector:@selector(tabView:toolTipForTabViewItem:)]) { + return [[self delegate] tabView:[self tabView] toolTipForTabViewItem:[[self cellForPoint:point cellFrame:nil] representedObject]]; + } + return nil; } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [super encodeWithCoder:aCoder]; - if ([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_cells forKey:@"PSMcells"]; - [aCoder encodeObject:tabView forKey:@"PSMtabView"]; - [aCoder encodeObject:_overflowPopUpButton forKey:@"PSMoverflowPopUpButton"]; - [aCoder encodeObject:_addTabButton forKey:@"PSMaddTabButton"]; - [aCoder encodeObject:style forKey:@"PSMstyle"]; - [aCoder encodeInteger:_orientation forKey:@"PSMorientation"]; - [aCoder encodeBool:_canCloseOnlyTab forKey:@"PSMcanCloseOnlyTab"]; - [aCoder encodeBool:_disableTabClose forKey:@"PSMdisableTabClose"]; - [aCoder encodeBool:_hideForSingleTab forKey:@"PSMhideForSingleTab"]; - [aCoder encodeBool:_allowsBackgroundTabClosing forKey:@"PSMallowsBackgroundTabClosing"]; - [aCoder encodeBool:_allowsResizing forKey:@"PSMallowsResizing"]; - [aCoder encodeBool:_selectsTabsOnMouseDown forKey:@"PSMselectsTabsOnMouseDown"]; - [aCoder encodeBool:_showAddTabButton forKey:@"PSMshowAddTabButton"]; - [aCoder encodeBool:_sizeCellsToFit forKey:@"PSMsizeCellsToFit"]; - [aCoder encodeInteger:_cellMinWidth forKey:@"PSMcellMinWidth"]; - [aCoder encodeInteger:_cellMaxWidth forKey:@"PSMcellMaxWidth"]; - [aCoder encodeInteger:_cellOptimumWidth forKey:@"PSMcellOptimumWidth"]; - [aCoder encodeInteger:_currentStep forKey:@"PSMcurrentStep"]; - [aCoder encodeBool:_isHidden forKey:@"PSMisHidden"]; - [aCoder encodeObject:partnerView forKey:@"PSMpartnerView"]; - [aCoder encodeBool:_awakenedFromNib forKey:@"PSMawakenedFromNib"]; - [aCoder encodeObject:_lastMouseDownEvent forKey:@"PSMlastMouseDownEvent"]; - [aCoder encodeObject:delegate forKey:@"PSMdelegate"]; - [aCoder encodeBool:_useOverflowMenu forKey:@"PSMuseOverflowMenu"]; - [aCoder encodeBool:_automaticallyAnimates forKey:@"PSMautomaticallyAnimates"]; - [aCoder encodeBool:_alwaysShowActiveTab forKey:@"PSMalwaysShowActiveTab"]; - } -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [super initWithCoder:aDecoder]; - if (self) { - // Initialization - [self initAddedProperties]; - [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; - - // resize - [self setPostsFrameChangedNotifications:YES]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; - if ([aDecoder allowsKeyedCoding]) { - _cells = [aDecoder decodeObjectForKey:@"PSMcells"] ; - tabView = [aDecoder decodeObjectForKey:@"PSMtabView"] ; - _overflowPopUpButton = [aDecoder decodeObjectForKey:@"PSMoverflowPopUpButton"] ; - _addTabButton = [aDecoder decodeObjectForKey:@"PSMaddTabButton"] ; - style = [aDecoder decodeObjectForKey:@"PSMstyle"] ; - _orientation = (PSMTabBarOrientation)[aDecoder decodeIntegerForKey:@"PSMorientation"]; - _canCloseOnlyTab = [aDecoder decodeBoolForKey:@"PSMcanCloseOnlyTab"]; - _disableTabClose = [aDecoder decodeBoolForKey:@"PSMdisableTabClose"]; - _hideForSingleTab = [aDecoder decodeBoolForKey:@"PSMhideForSingleTab"]; - _allowsBackgroundTabClosing = [aDecoder decodeBoolForKey:@"PSMallowsBackgroundTabClosing"]; - _allowsResizing = [aDecoder decodeBoolForKey:@"PSMallowsResizing"]; - _selectsTabsOnMouseDown = [aDecoder decodeBoolForKey:@"PSMselectsTabsOnMouseDown"]; - _showAddTabButton = [aDecoder decodeBoolForKey:@"PSMshowAddTabButton"]; - _sizeCellsToFit = [aDecoder decodeBoolForKey:@"PSMsizeCellsToFit"]; - _cellMinWidth = [aDecoder decodeIntegerForKey:@"PSMcellMinWidth"]; - _cellMaxWidth = [aDecoder decodeIntegerForKey:@"PSMcellMaxWidth"]; - _cellOptimumWidth = [aDecoder decodeIntegerForKey:@"PSMcellOptimumWidth"]; - _currentStep = [aDecoder decodeIntegerForKey:@"PSMcurrentStep"]; - _isHidden = [aDecoder decodeBoolForKey:@"PSMisHidden"]; - partnerView = [aDecoder decodeObjectForKey:@"PSMpartnerView"] ; - _awakenedFromNib = [aDecoder decodeBoolForKey:@"PSMawakenedFromNib"]; - _lastMouseDownEvent = [aDecoder decodeObjectForKey:@"PSMlastMouseDownEvent"] ; - _useOverflowMenu = [aDecoder decodeBoolForKey:@"PSMuseOverflowMenu"]; - _automaticallyAnimates = [aDecoder decodeBoolForKey:@"PSMautomaticallyAnimates"]; - _alwaysShowActiveTab = [aDecoder decodeBoolForKey:@"PSMalwaysShowActiveTab"]; - delegate = [aDecoder decodeObjectForKey:@"PSMdelegate"] ; - } - } - [self setTarget:self]; - return self; +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_cells forKey:@"PSMcells"]; + [aCoder encodeObject:tabView forKey:@"PSMtabView"]; + [aCoder encodeObject:_overflowPopUpButton forKey:@"PSMoverflowPopUpButton"]; + [aCoder encodeObject:_addTabButton forKey:@"PSMaddTabButton"]; + [aCoder encodeObject:style forKey:@"PSMstyle"]; + [aCoder encodeInteger:_orientation forKey:@"PSMorientation"]; + [aCoder encodeBool:_canCloseOnlyTab forKey:@"PSMcanCloseOnlyTab"]; + [aCoder encodeBool:_disableTabClose forKey:@"PSMdisableTabClose"]; + [aCoder encodeBool:_hideForSingleTab forKey:@"PSMhideForSingleTab"]; + [aCoder encodeBool:_allowsBackgroundTabClosing forKey:@"PSMallowsBackgroundTabClosing"]; + [aCoder encodeBool:_allowsResizing forKey:@"PSMallowsResizing"]; + [aCoder encodeBool:_selectsTabsOnMouseDown forKey:@"PSMselectsTabsOnMouseDown"]; + [aCoder encodeBool:_showAddTabButton forKey:@"PSMshowAddTabButton"]; + [aCoder encodeBool:_sizeCellsToFit forKey:@"PSMsizeCellsToFit"]; + [aCoder encodeInteger:_cellMinWidth forKey:@"PSMcellMinWidth"]; + [aCoder encodeInteger:_cellMaxWidth forKey:@"PSMcellMaxWidth"]; + [aCoder encodeInteger:_cellOptimumWidth forKey:@"PSMcellOptimumWidth"]; + [aCoder encodeInteger:_currentStep forKey:@"PSMcurrentStep"]; + [aCoder encodeBool:_isHidden forKey:@"PSMisHidden"]; + [aCoder encodeObject:partnerView forKey:@"PSMpartnerView"]; + [aCoder encodeBool:_awakenedFromNib forKey:@"PSMawakenedFromNib"]; + [aCoder encodeObject:_lastMouseDownEvent forKey:@"PSMlastMouseDownEvent"]; + [aCoder encodeObject:delegate forKey:@"PSMdelegate"]; + [aCoder encodeBool:_useOverflowMenu forKey:@"PSMuseOverflowMenu"]; + [aCoder encodeBool:_automaticallyAnimates forKey:@"PSMautomaticallyAnimates"]; + [aCoder encodeBool:_alwaysShowActiveTab forKey:@"PSMalwaysShowActiveTab"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + // Initialization + [self initAddedProperties]; + [self registerForDraggedTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil]]; + + // resize + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; + if ([aDecoder allowsKeyedCoding]) { + _cells = [aDecoder decodeObjectForKey:@"PSMcells"]; + tabView = [aDecoder decodeObjectForKey:@"PSMtabView"]; + _overflowPopUpButton = [aDecoder decodeObjectForKey:@"PSMoverflowPopUpButton"]; + _addTabButton = [aDecoder decodeObjectForKey:@"PSMaddTabButton"]; + style = [aDecoder decodeObjectForKey:@"PSMstyle"]; + _orientation = (PSMTabBarOrientation)[aDecoder decodeIntegerForKey:@"PSMorientation"]; + _canCloseOnlyTab = [aDecoder decodeBoolForKey:@"PSMcanCloseOnlyTab"]; + _disableTabClose = [aDecoder decodeBoolForKey:@"PSMdisableTabClose"]; + _hideForSingleTab = [aDecoder decodeBoolForKey:@"PSMhideForSingleTab"]; + _allowsBackgroundTabClosing = [aDecoder decodeBoolForKey:@"PSMallowsBackgroundTabClosing"]; + _allowsResizing = [aDecoder decodeBoolForKey:@"PSMallowsResizing"]; + _selectsTabsOnMouseDown = [aDecoder decodeBoolForKey:@"PSMselectsTabsOnMouseDown"]; + _showAddTabButton = [aDecoder decodeBoolForKey:@"PSMshowAddTabButton"]; + _sizeCellsToFit = [aDecoder decodeBoolForKey:@"PSMsizeCellsToFit"]; + _cellMinWidth = [aDecoder decodeIntegerForKey:@"PSMcellMinWidth"]; + _cellMaxWidth = [aDecoder decodeIntegerForKey:@"PSMcellMaxWidth"]; + _cellOptimumWidth = [aDecoder decodeIntegerForKey:@"PSMcellOptimumWidth"]; + _currentStep = [aDecoder decodeIntegerForKey:@"PSMcurrentStep"]; + _isHidden = [aDecoder decodeBoolForKey:@"PSMisHidden"]; + partnerView = [aDecoder decodeObjectForKey:@"PSMpartnerView"]; + _awakenedFromNib = [aDecoder decodeBoolForKey:@"PSMawakenedFromNib"]; + _lastMouseDownEvent = [aDecoder decodeObjectForKey:@"PSMlastMouseDownEvent"]; + _useOverflowMenu = [aDecoder decodeBoolForKey:@"PSMuseOverflowMenu"]; + _automaticallyAnimates = [aDecoder decodeBoolForKey:@"PSMautomaticallyAnimates"]; + _alwaysShowActiveTab = [aDecoder decodeBoolForKey:@"PSMalwaysShowActiveTab"]; + delegate = [aDecoder decodeObjectForKey:@"PSMdelegate"]; + } + } + [self setTarget:self]; + return self; } #pragma mark - #pragma mark IB Palette -- (NSSize)minimumFrameSizeFromKnobPosition:(NSInteger)position { - return NSMakeSize(100.0, 22.0); +- (NSSize)minimumFrameSizeFromKnobPosition:(NSInteger)position +{ + return NSMakeSize(100.0, 22.0); } -- (NSSize)maximumFrameSizeFromKnobPosition:(NSInteger)knobPosition { - return NSMakeSize(10000.0, 22.0); +- (NSSize)maximumFrameSizeFromKnobPosition:(NSInteger)knobPosition +{ + return NSMakeSize(10000.0, 22.0); } -- (void)placeView:(NSRect)newFrame { - // this is called any time the view is resized in IB - [self setFrame:newFrame]; - [self update:NO]; +- (void)placeView:(NSRect)newFrame +{ + // this is called any time the view is resized in IB + [self setFrame:newFrame]; + [self update:NO]; } #pragma mark - #pragma mark Convenience -- (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item { - [self _bindPropertiesForCell:cell andTabViewItem:item]; - - // watch for changes in the identifier - [item addObserver:self forKeyPath:@"identifier" options:0 context:nil]; -} - -- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item { - // bind the indicator to the represented object's status (if it exists) - [[cell indicator] setHidden:YES]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(isProcessing)]) { - NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; - [bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"]; - [[cell indicator] bind:@"animate" toObject:[item identifier] withKeyPath:@"isProcessing" options:nil]; - [[cell indicator] bind:@"hidden" toObject:[item identifier] withKeyPath:@"isProcessing" options:bindingOptions]; - [[item identifier] addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil]; - } - } - - // bind for the existence of an icon - [cell setHasIcon:NO]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(icon)]) { - NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; - [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; - [cell bind:@"hasIcon" toObject:[item identifier] withKeyPath:@"icon" options:bindingOptions]; - [[item identifier] addObserver:cell forKeyPath:@"icon" options:0 context:nil]; - } - } - - // bind for the existence of a counter - [cell setCount:0]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(objectCount)]) { - [cell bind:@"count" toObject:[item identifier] withKeyPath:@"objectCount" options:nil]; - [[item identifier] addObserver:cell forKeyPath:@"objectCount" options:0 context:nil]; - } - } - - // bind for the color of a counter - [cell setCountColor:nil]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(countColor)]) { - [cell bind:@"countColor" toObject:[item identifier] withKeyPath:@"countColor" options:nil]; - [[item identifier] addObserver:cell forKeyPath:@"countColor" options:0 context:nil]; - } - } - - // bind for a large image - [cell setHasLargeImage:NO]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(largeImage)]) { - NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; - [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; - [cell bind:@"hasLargeImage" toObject:[item identifier] withKeyPath:@"largeImage" options:bindingOptions]; - [[item identifier] addObserver:cell forKeyPath:@"largeImage" options:0 context:nil]; - } - } - - [cell setIsEdited:NO]; - if([item identifier] != nil) { - if([[[cell representedObject] identifier] respondsToSelector:@selector(isEdited)]) { - [cell bind:@"isEdited" toObject:[item identifier] withKeyPath:@"isEdited" options:nil]; - [[item identifier] addObserver:cell forKeyPath:@"isEdited" options:0 context:nil]; - } - } - - // bind my string value to the label on the represented tab - [cell bind:@"title" toObject:item withKeyPath:@"label" options:nil]; -} - -- (NSMutableArray *)representedTabViewItems { - NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[_cells count]]; - NSEnumerator *e = [_cells objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - if([cell representedObject]) { - [temp addObject:[cell representedObject]]; - } - } - return temp; -} - -- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame { - if([self orientation] == PSMTabBarHorizontalOrientation && !NSPointInRect(point, [self genericCellRect])) { - return nil; - } - - NSInteger i, cnt = [_cells count]; - for(i = 0; i < cnt; i++) { - PSMTabBarCell *cell = [_cells objectAtIndex:i]; - - if(NSPointInRect(point, [cell frame])) { - if(outFrame) { - *outFrame = [cell frame]; - } - return cell; - } - } - return nil; -} - -- (PSMTabBarCell *)lastVisibleTab { - NSInteger i, cellCount = [_cells count]; - for(i = 0; i < cellCount; i++) { - if([[_cells objectAtIndex:i] isInOverflowMenu]) { - return [_cells objectAtIndex:(i - 1)]; - } - } - return [_cells objectAtIndex:(cellCount - 1)]; -} - -- (NSInteger)numberOfVisibleTabs { - NSUInteger i, cellCount = 0; - PSMTabBarCell *nextCell; - - for(i = 0; i < [_cells count]; i++) { - nextCell = [_cells objectAtIndex:i]; - - if([nextCell isInOverflowMenu]) { - break; - } - - if(![nextCell isPlaceholder]) { - cellCount++; - } - } - - return cellCount; +- (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item +{ + [self _bindPropertiesForCell:cell andTabViewItem:item]; + + // watch for changes in the identifier + [item addObserver:self forKeyPath:@"identifier" options:0 context:nil]; } -#pragma mark - -#pragma mark Accessibility +- (void)_bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item +{ + // bind the indicator to the represented object's status (if it exists) + [[cell indicator] setHidden:YES]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(isProcessing)]) { + NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; + [bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"]; + [[cell indicator] bind:@"animate" toObject:[item identifier] withKeyPath:@"isProcessing" options:nil]; + [[cell indicator] bind:@"hidden" toObject:[item identifier] withKeyPath:@"isProcessing" options:bindingOptions]; + [[item identifier] addObserver:cell forKeyPath:@"isProcessing" options:0 context:nil]; + } + } + + // bind for the existence of an icon + [cell setHasIcon:NO]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(icon)]) { + NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; + [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; + [cell bind:@"hasIcon" toObject:[item identifier] withKeyPath:@"icon" options:bindingOptions]; + [[item identifier] addObserver:cell forKeyPath:@"icon" options:0 context:nil]; + } + } + + // bind for the existence of a counter + [cell setCount:0]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(objectCount)]) { + [cell bind:@"count" toObject:[item identifier] withKeyPath:@"objectCount" options:nil]; + [[item identifier] addObserver:cell forKeyPath:@"objectCount" options:0 context:nil]; + } + } + + // bind for the color of a counter + [cell setCountColor:nil]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(countColor)]) { + [cell bind:@"countColor" toObject:[item identifier] withKeyPath:@"countColor" options:nil]; + [[item identifier] addObserver:cell forKeyPath:@"countColor" options:0 context:nil]; + } + } + + // bind for a large image + [cell setHasLargeImage:NO]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(largeImage)]) { + NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; + [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; + [cell bind:@"hasLargeImage" toObject:[item identifier] withKeyPath:@"largeImage" options:bindingOptions]; + [[item identifier] addObserver:cell forKeyPath:@"largeImage" options:0 context:nil]; + } + } + + [cell setIsEdited:NO]; + if ([item identifier] != nil) { + if ([[[cell representedObject] identifier] respondsToSelector:@selector(isEdited)]) { + [cell bind:@"isEdited" toObject:[item identifier] withKeyPath:@"isEdited" options:nil]; + [[item identifier] addObserver:cell forKeyPath:@"isEdited" options:0 context:nil]; + } + } + + // bind my string value to the label on the represented tab + [cell bind:@"title" toObject:item withKeyPath:@"label" options:nil]; +} + +- (NSMutableArray *)representedTabViewItems +{ + NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[_cells count]]; + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + if ([cell representedObject]) { + [temp addObject:[cell representedObject]]; + } + } + return temp; +} + +- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame +{ + if ([self orientation] == PSMTabBarHorizontalOrientation && !NSPointInRect(point, [self genericCellRect])) { + return nil; + } + + NSInteger i, cnt = [_cells count]; + for (i = 0; i < cnt; i++) { + PSMTabBarCell *cell = [_cells objectAtIndex:i]; --(BOOL)accessibilityIsIgnored { - return NO; + if (NSPointInRect(point, [cell frame])) { + if (outFrame) { + *outFrame = [cell frame]; + } + return cell; + } + } + return nil; } -- (id)accessibilityAttributeValue:(NSString *)attribute { - id attributeValue = nil; - if([attribute isEqualToString: NSAccessibilityRoleAttribute]) { - attributeValue = NSAccessibilityGroupRole; - } else if([attribute isEqualToString: NSAccessibilityChildrenAttribute]) { - attributeValue = NSAccessibilityUnignoredChildren(_cells); - } else { - attributeValue = [super accessibilityAttributeValue:attribute]; - } - return attributeValue; +- (PSMTabBarCell *)lastVisibleTab +{ + NSInteger i, cellCount = [_cells count]; + for (i = 0; i < cellCount; i++) { + if ([[_cells objectAtIndex:i] isInOverflowMenu]) { + return [_cells objectAtIndex:(i - 1)]; + } + } + return [_cells objectAtIndex:(cellCount - 1)]; } -- (id)accessibilityHitTest:(NSPoint)point { - id hitTestResult = self; +- (NSInteger)numberOfVisibleTabs +{ + NSUInteger i, cellCount = 0; + PSMTabBarCell *nextCell; + + for (i = 0; i < [_cells count]; i++) { + nextCell = [_cells objectAtIndex:i]; + + if ([nextCell isInOverflowMenu]) { + break; + } + + if (![nextCell isPlaceholder]) { + cellCount++; + } + } + + return cellCount; +} + +#pragma mark - +#pragma mark Accessibility + +- (BOOL)accessibilityIsIgnored +{ + return NO; +} + +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + id attributeValue = nil; + if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { + attributeValue = NSAccessibilityGroupRole; + } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { + attributeValue = NSAccessibilityUnignoredChildren(_cells); + } else { + attributeValue = [super accessibilityAttributeValue:attribute]; + } + return attributeValue; +} + +- (id)accessibilityHitTest:(NSPoint)point +{ + id hitTestResult = self; - NSEnumerator *enumerator = [_cells objectEnumerator]; - PSMTabBarCell *cell = nil; - PSMTabBarCell *highlightedCell = nil; + NSEnumerator *enumerator = [_cells objectEnumerator]; + PSMTabBarCell *cell = nil; + PSMTabBarCell *highlightedCell = nil; - while(!highlightedCell && (cell = [enumerator nextObject])) { - if([cell isHighlighted]) { - highlightedCell = cell; - } - } + while (!highlightedCell && (cell = [enumerator nextObject])) { + if ([cell isHighlighted]) { + highlightedCell = cell; + } + } - if(highlightedCell) { - hitTestResult = [highlightedCell accessibilityHitTest:point]; - } + if (highlightedCell) { + hitTestResult = [highlightedCell accessibilityHitTest:point]; + } - return hitTestResult; + return hitTestResult; } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabBarController.m b/frontends/cocoa/PSMTabBarControl/PSMTabBarController.m index ea3f5baa3..232bb4948 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabBarController.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabBarController.m @@ -13,7 +13,7 @@ #import "NSString_AITruncation.h" #import "PSMRolloverButton.h" -#define MAX_OVERFLOW_MENUITEM_TITLE_LENGTH 60 +#define MAX_OVERFLOW_MENUITEM_TITLE_LENGTH 60 @interface PSMTabBarController (Private) - (NSArray *)_generateWidthsFromCells:(NSArray *)cells; @@ -31,15 +31,16 @@ @returns A newly created PSMTabBarController instance. */ -- (id)initWithTabBarControl:(PSMTabBarControl *)control { - if((self = [super init])) { - _control = control; - _cellTrackingRects = [[NSMutableArray alloc] init]; - _closeButtonTrackingRects = [[NSMutableArray alloc] init]; - _cellFrames = [[NSMutableArray alloc] init]; - _addButtonRect = NSZeroRect; - } - return self; +- (id)initWithTabBarControl:(PSMTabBarControl *)control +{ + if ((self = [super init])) { + _control = control; + _cellTrackingRects = [[NSMutableArray alloc] init]; + _closeButtonTrackingRects = [[NSMutableArray alloc] init]; + _cellFrames = [[NSMutableArray alloc] init]; + _addButtonRect = NSZeroRect; + } + return self; } /*! @@ -49,8 +50,9 @@ @returns The rect for the add button rect. */ -- (NSRect)addButtonRect { - return _addButtonRect; +- (NSRect)addButtonRect +{ + return _addButtonRect; } /*! @@ -60,8 +62,9 @@ @returns The current overflow menu. */ -- (NSMenu *)overflowMenu { - return _overflowMenu; +- (NSMenu *)overflowMenu +{ + return _overflowMenu; } /*! @@ -72,15 +75,16 @@ @returns The tracking rect of the cell at the requested index. */ -- (NSRect)cellTrackingRectAtIndex:(NSUInteger)index { - NSRect rect; - if(index < [_cellTrackingRects count]) { - rect = [[_cellTrackingRects objectAtIndex:index] rectValue]; - } else { - NSLog(@"cellTrackingRectAtIndex: Invalid index (%ld)", (long)index); - rect = NSZeroRect; - } - return rect; +- (NSRect)cellTrackingRectAtIndex:(NSUInteger)index +{ + NSRect rect; + if (index < [_cellTrackingRects count]) { + rect = [[_cellTrackingRects objectAtIndex:index] rectValue]; + } else { + NSLog(@"cellTrackingRectAtIndex: Invalid index (%ld)", (long)index); + rect = NSZeroRect; + } + return rect; } /*! @@ -91,15 +95,16 @@ @returns The close button tracking rect of the cell at the requested index. */ -- (NSRect)closeButtonTrackingRectAtIndex:(NSUInteger)index { - NSRect rect; - if(index < [_closeButtonTrackingRects count]) { - rect = [[_closeButtonTrackingRects objectAtIndex:index] rectValue]; - } else { - NSLog(@"closeButtonTrackingRectAtIndex: Invalid index (%ld)", (long)index); - rect = NSZeroRect; - } - return rect; +- (NSRect)closeButtonTrackingRectAtIndex:(NSUInteger)index +{ + NSRect rect; + if (index < [_closeButtonTrackingRects count]) { + rect = [[_closeButtonTrackingRects objectAtIndex:index] rectValue]; + } else { + NSLog(@"closeButtonTrackingRectAtIndex: Invalid index (%ld)", (long)index); + rect = NSZeroRect; + } + return rect; } /*! @@ -110,16 +115,17 @@ @returns The frame of the cell at the requested index. */ -- (NSRect)cellFrameAtIndex:(NSUInteger)index { - NSRect rect; - - if(index < [_cellFrames count]) { - rect = [[_cellFrames objectAtIndex:index] rectValue]; - } else { - NSLog(@"cellFrameAtIndex: Invalid index (%ld)", (long)index); - rect = NSZeroRect; - } - return rect; +- (NSRect)cellFrameAtIndex:(NSUInteger)index +{ + NSRect rect; + + if (index < [_cellFrames count]) { + rect = [[_cellFrames objectAtIndex:index] rectValue]; + } else { + NSLog(@"cellFrameAtIndex: Invalid index (%ld)", (long)index); + rect = NSZeroRect; + } + return rect; } /*! @@ -129,43 +135,44 @@ @param An instance of PSMTabBarCell to make active. */ -- (void)setSelectedCell:(PSMTabBarCell *)cell { - NSArray *cells = [_control cells]; - NSEnumerator *enumerator = [cells objectEnumerator]; - PSMTabBarCell *lastCell = nil, *nextCell; +- (void)setSelectedCell:(PSMTabBarCell *)cell +{ + NSArray *cells = [_control cells]; + NSEnumerator *enumerator = [cells objectEnumerator]; + PSMTabBarCell *lastCell = nil, *nextCell; - //deselect the previously selected tab - while((nextCell = [enumerator nextObject]) && ([nextCell state] == NSOffState)) { - lastCell = nextCell; - } + //deselect the previously selected tab + while ((nextCell = [enumerator nextObject]) && ([nextCell state] == NSOffState)) { + lastCell = nextCell; + } - [nextCell setState:NSOffState]; - [nextCell setTabState:PSMTab_PositionMiddleMask]; + [nextCell setState:NSOffState]; + [nextCell setTabState:PSMTab_PositionMiddleMask]; - if(lastCell && lastCell != [_control lastVisibleTab]) { - [lastCell setTabState:~[lastCell tabState] & PSMTab_RightIsSelectedMask]; - } + if (lastCell && lastCell != [_control lastVisibleTab]) { + [lastCell setTabState:~[lastCell tabState] & PSMTab_RightIsSelectedMask]; + } - if((nextCell = [enumerator nextObject])) { - [nextCell setTabState:~[lastCell tabState] & PSMTab_LeftIsSelectedMask]; - } + if ((nextCell = [enumerator nextObject])) { + [nextCell setTabState:~[lastCell tabState] & PSMTab_LeftIsSelectedMask]; + } - [cell setState:NSOnState]; - [cell setTabState:PSMTab_SelectedMask]; + [cell setState:NSOnState]; + [cell setTabState:PSMTab_SelectedMask]; - if(![cell isInOverflowMenu]) { - NSUInteger cellIndex = [cells indexOfObject:cell]; + if (![cell isInOverflowMenu]) { + NSUInteger cellIndex = [cells indexOfObject:cell]; - if(cellIndex > 0) { - nextCell = [cells objectAtIndex:cellIndex - 1]; - [nextCell setTabState:[nextCell tabState] | PSMTab_RightIsSelectedMask]; - } + if (cellIndex > 0) { + nextCell = [cells objectAtIndex:cellIndex - 1]; + [nextCell setTabState:[nextCell tabState] | PSMTab_RightIsSelectedMask]; + } - if(cellIndex < [cells count] - 1) { - nextCell = [cells objectAtIndex:cellIndex + 1]; - [nextCell setTabState:[nextCell tabState] | PSMTab_LeftIsSelectedMask]; - } - } + if (cellIndex < [cells count] - 1) { + nextCell = [cells objectAtIndex:cellIndex + 1]; + [nextCell setTabState:[nextCell tabState] | PSMTab_LeftIsSelectedMask]; + } + } } /*! @@ -175,32 +182,33 @@ tab bar control. */ -- (void)layoutCells { - NSArray *cells = [_control cells]; - NSInteger cellCount = [cells count]; - - // make sure all of our tabs are accounted for before updating - if([[_control tabView] numberOfTabViewItems] != cellCount) { - return; - } - - [_cellTrackingRects removeAllObjects]; - [_closeButtonTrackingRects removeAllObjects]; - [_cellFrames removeAllObjects]; - - NSArray *cellWidths = [self _generateWidthsFromCells:cells]; - [self _setupCells:cells withWidths:cellWidths]; - - //set up the rect from the add tab button - _addButtonRect = [_control genericCellRect]; - _addButtonRect.size = [[_control addTabButton] frame].size; - if([_control orientation] == PSMTabBarHorizontalOrientation) { - _addButtonRect.origin.y = MARGIN_Y; - _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] doubleValue] + 2; - } else { - _addButtonRect.origin.x = 0; - _addButtonRect.origin.y = [[cellWidths lastObject] doubleValue]; - } +- (void)layoutCells +{ + NSArray *cells = [_control cells]; + NSInteger cellCount = [cells count]; + + // make sure all of our tabs are accounted for before updating + if ([[_control tabView] numberOfTabViewItems] != cellCount) { + return; + } + + [_cellTrackingRects removeAllObjects]; + [_closeButtonTrackingRects removeAllObjects]; + [_cellFrames removeAllObjects]; + + NSArray *cellWidths = [self _generateWidthsFromCells:cells]; + [self _setupCells:cells withWidths:cellWidths]; + + //set up the rect from the add tab button + _addButtonRect = [_control genericCellRect]; + _addButtonRect.size = [[_control addTabButton] frame].size; + if ([_control orientation] == PSMTabBarHorizontalOrientation) { + _addButtonRect.origin.y = MARGIN_Y; + _addButtonRect.origin.x += [[cellWidths valueForKeyPath:@"@sum.floatValue"] doubleValue] + 2; + } else { + _addButtonRect.origin.x = 0; + _addButtonRect.origin.y = [[cellWidths lastObject] doubleValue]; + } } /*! @@ -211,30 +219,31 @@ * @param The maximum available width * @returns The amount by which the total array width was shrunk */ -- (NSInteger)_shrinkWidths:(NSMutableArray *)newWidths towardMinimum:(NSInteger)minimum withAvailableWidth:(CGFloat)availableWidth { - BOOL changed = NO; - NSInteger count = [newWidths count]; - NSInteger totalWidths = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; - NSInteger originalTotalWidths = totalWidths; - - do { - changed = NO; - - for(NSInteger q = (count - 1); q >= 0; q--) { - CGFloat cellWidth = [[newWidths objectAtIndex:q] doubleValue]; - if(cellWidth - 1 >= minimum) { - cellWidth--; - totalWidths--; - - [newWidths replaceObjectAtIndex:q - withObject:[NSNumber numberWithDouble:cellWidth]]; - - changed = YES; - } - } - } while(changed && (totalWidths > availableWidth)); - - return(originalTotalWidths - totalWidths); +- (NSInteger)_shrinkWidths:(NSMutableArray *)newWidths towardMinimum:(NSInteger)minimum withAvailableWidth:(CGFloat)availableWidth +{ + BOOL changed = NO; + NSInteger count = [newWidths count]; + NSInteger totalWidths = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; + NSInteger originalTotalWidths = totalWidths; + + do { + changed = NO; + + for (NSInteger q = (count - 1); q >= 0; q--) { + CGFloat cellWidth = [[newWidths objectAtIndex:q] doubleValue]; + if (cellWidth - 1 >= minimum) { + cellWidth--; + totalWidths--; + + [newWidths replaceObjectAtIndex:q + withObject:[NSNumber numberWithDouble:cellWidth]]; + + changed = YES; + } + } + } while (changed && (totalWidths > availableWidth)); + + return (originalTotalWidths - totalWidths); } /*! @@ -247,16 +256,17 @@ * @param The minimum * @returns The smallest possible sum for the array */ -static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum){ - NSInteger runningTotal = 0; - NSInteger count = [array count]; +static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum) +{ + NSInteger runningTotal = 0; + NSInteger count = [array count]; - for(NSInteger i = 0; i < count; i++) { - NSInteger currentValue = [[array objectAtIndex:i] integerValue]; - runningTotal += MIN(currentValue, minimum); - } + for (NSInteger i = 0; i < count; i++) { + NSInteger currentValue = [[array objectAtIndex:i] integerValue]; + runningTotal += MIN(currentValue, minimum); + } - return runningTotal; + return runningTotal; } /*! @@ -268,224 +278,222 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum){ @returns An array of numbers representing the widths of cells that would be visible. */ -- (NSArray *)_generateWidthsFromCells:(NSArray *)cells { - NSInteger cellCount = [cells count], i, numberOfVisibleCells = ([_control orientation] == PSMTabBarHorizontalOrientation) ? 1 : 0; - NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount]; - id style = [_control style]; - CGFloat availableWidth = [_control availableCellWidth], currentOrigin = 0, totalOccupiedWidth = 0.0, width; - NSRect cellRect = [_control genericCellRect], controlRect = [_control frame]; - PSMTabBarCell *currentCell; - - if([_control orientation] == PSMTabBarVerticalOrientation) { - currentOrigin = [style topMarginForTabBarControl]; - } - - //Don't let cells overlap the add tab button if it is visible - if([_control showAddTabButton]) { - availableWidth -= [self addButtonRect].size.width; - } - - for(i = 0; i < cellCount; i++) { - currentCell = [cells objectAtIndex:i]; - - // supress close button? - [currentCell setCloseButtonSuppressed:((cellCount == 1 && [_control canCloseOnlyTab] == NO) || - [_control disableTabClose] || - ([[_control delegate] respondsToSelector:@selector(tabView:disableTabCloseForTabViewItem:)] && - [[_control delegate] tabView:[_control tabView] disableTabCloseForTabViewItem:[currentCell representedObject]]))]; - - if([_control orientation] == PSMTabBarHorizontalOrientation) { - // Determine cell width - if([_control sizeCellsToFit]) { - width = [currentCell desiredWidthOfCell]; - if(width > [_control cellMaxWidth]) { - width = [_control cellMaxWidth]; - } - } else { - width = [_control cellOptimumWidth]; - } - - width = ceil(width); - - //check to see if there is not enough space to place all tabs as preferred - if(totalOccupiedWidth + width >= availableWidth) { - //There's not enough space to add currentCell at its preferred width! - - //If we're not going to use the overflow menu, cram all the tab cells into the bar regardless of minimum width - if(![_control useOverflowMenu]) { - NSInteger j, averageWidth = (availableWidth / cellCount); - - numberOfVisibleCells = cellCount; - [newWidths removeAllObjects]; - - for(j = 0; j < cellCount; j++) { - CGFloat desiredWidth = [[cells objectAtIndex:j] desiredWidthOfCell]; - [newWidths addObject:[NSNumber numberWithDouble:(desiredWidth < averageWidth && [_control sizeCellsToFit]) ? desiredWidth : averageWidth]]; - } - - totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; - break; - } - - //We'll be using the overflow menu if needed. - numberOfVisibleCells = i; - if([_control sizeCellsToFit]) { - BOOL remainingCellsMustGoToOverflow = NO; - - totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; - - /* Can I squeeze it in without violating min cell width? This is the width we would take up +- (NSArray *)_generateWidthsFromCells:(NSArray *)cells +{ + NSInteger cellCount = [cells count], i, numberOfVisibleCells = ([_control orientation] == PSMTabBarHorizontalOrientation) ? 1 : 0; + NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount]; + id style = [_control style]; + CGFloat availableWidth = [_control availableCellWidth], currentOrigin = 0, totalOccupiedWidth = 0.0, width; + NSRect cellRect = [_control genericCellRect], controlRect = [_control frame]; + PSMTabBarCell *currentCell; + + if ([_control orientation] == PSMTabBarVerticalOrientation) { + currentOrigin = [style topMarginForTabBarControl]; + } + + //Don't let cells overlap the add tab button if it is visible + if ([_control showAddTabButton]) { + availableWidth -= [self addButtonRect].size.width; + } + + for (i = 0; i < cellCount; i++) { + currentCell = [cells objectAtIndex:i]; + + // supress close button? + [currentCell setCloseButtonSuppressed:((cellCount == 1 && [_control canCloseOnlyTab] == NO) || + [_control disableTabClose] || ([[_control delegate] respondsToSelector:@selector(tabView:disableTabCloseForTabViewItem:)] && [[_control delegate] tabView:[_control tabView] + disableTabCloseForTabViewItem:[currentCell representedObject]]))]; + + if ([_control orientation] == PSMTabBarHorizontalOrientation) { + // Determine cell width + if ([_control sizeCellsToFit]) { + width = [currentCell desiredWidthOfCell]; + if (width > [_control cellMaxWidth]) { + width = [_control cellMaxWidth]; + } + } else { + width = [_control cellOptimumWidth]; + } + + width = ceil(width); + + //check to see if there is not enough space to place all tabs as preferred + if (totalOccupiedWidth + width >= availableWidth) { + //There's not enough space to add currentCell at its preferred width! + + //If we're not going to use the overflow menu, cram all the tab cells into the bar regardless of minimum width + if (![_control useOverflowMenu]) { + NSInteger j, averageWidth = (availableWidth / cellCount); + + numberOfVisibleCells = cellCount; + [newWidths removeAllObjects]; + + for (j = 0; j < cellCount; j++) { + CGFloat desiredWidth = [[cells objectAtIndex:j] desiredWidthOfCell]; + [newWidths addObject:[NSNumber numberWithDouble:(desiredWidth < averageWidth && [_control sizeCellsToFit]) ? desiredWidth : averageWidth]]; + } + + totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; + break; + } + + //We'll be using the overflow menu if needed. + numberOfVisibleCells = i; + if ([_control sizeCellsToFit]) { + BOOL remainingCellsMustGoToOverflow = NO; + + totalOccupiedWidth = [[newWidths valueForKeyPath:@"@sum.intValue"] integerValue]; + + /* Can I squeeze it in without violating min cell width? This is the width we would take up * if every cell so far were at the control minimum size (or their current size if that is less than the control minimum). */ - if((potentialMinimumForArray(newWidths, [_control cellMinWidth]) + MIN(width, [_control cellMinWidth])) <= availableWidth) { - /* It's definitely possible for cells so far to be visible. + if ((potentialMinimumForArray(newWidths, [_control cellMinWidth]) + MIN(width, [_control cellMinWidth])) <= availableWidth) { + /* It's definitely possible for cells so far to be visible. * Shrink other cells to allow this one to fit */ - NSInteger cellMinWidth = [_control cellMinWidth]; + NSInteger cellMinWidth = [_control cellMinWidth]; - /* Start off adding it to the array; we know that it will eventually fit because + /* Start off adding it to the array; we know that it will eventually fit because * (the potential minimum <= availableWidth) * * This allows average and minimum aggregates on the NSArray to work. */ - [newWidths addObject:[NSNumber numberWithDouble:width]]; - numberOfVisibleCells++; - - totalOccupiedWidth += width; - - //First, try to shrink tabs toward the average. Tabs smaller than average won't change - totalOccupiedWidth -= [self _shrinkWidths:newWidths - towardMinimum:[[newWidths valueForKeyPath:@"@avg.intValue"] integerValue] - withAvailableWidth:availableWidth]; - - - - if(totalOccupiedWidth > availableWidth) { - //Next, shrink tabs toward the smallest of the existing tabs. The smallest tab won't change. - NSInteger smallestTabWidth = [[newWidths valueForKeyPath:@"@min.intValue"] integerValue]; - if(smallestTabWidth > cellMinWidth) { - totalOccupiedWidth -= [self _shrinkWidths:newWidths - towardMinimum:smallestTabWidth - withAvailableWidth:availableWidth]; - } - } - - if(totalOccupiedWidth > availableWidth) { - //Finally, shrink tabs toward the imposed minimum size. All tabs larger than the minimum wll change. - totalOccupiedWidth -= [self _shrinkWidths:newWidths - towardMinimum:cellMinWidth - withAvailableWidth:availableWidth]; - } - - if(totalOccupiedWidth > availableWidth) { - NSLog(@"**** -[PSMTabBarController generateWidthsFromCells:] This is a failure (available %f, total %f, width is %f)", - availableWidth, totalOccupiedWidth, width); - remainingCellsMustGoToOverflow = YES; - } - - if(totalOccupiedWidth < availableWidth) { - /* We're not using all available space not but exceeded available width before; + [newWidths addObject:[NSNumber numberWithDouble:width]]; + numberOfVisibleCells++; + + totalOccupiedWidth += width; + + //First, try to shrink tabs toward the average. Tabs smaller than average won't change + totalOccupiedWidth -= [self _shrinkWidths:newWidths + towardMinimum:[[newWidths valueForKeyPath:@"@avg.intValue"] integerValue] + withAvailableWidth:availableWidth]; + + if (totalOccupiedWidth > availableWidth) { + //Next, shrink tabs toward the smallest of the existing tabs. The smallest tab won't change. + NSInteger smallestTabWidth = [[newWidths valueForKeyPath:@"@min.intValue"] integerValue]; + if (smallestTabWidth > cellMinWidth) { + totalOccupiedWidth -= [self _shrinkWidths:newWidths + towardMinimum:smallestTabWidth + withAvailableWidth:availableWidth]; + } + } + + if (totalOccupiedWidth > availableWidth) { + //Finally, shrink tabs toward the imposed minimum size. All tabs larger than the minimum wll change. + totalOccupiedWidth -= [self _shrinkWidths:newWidths + towardMinimum:cellMinWidth + withAvailableWidth:availableWidth]; + } + + if (totalOccupiedWidth > availableWidth) { + NSLog(@"**** -[PSMTabBarController generateWidthsFromCells:] This is a failure (available %f, total %f, width is %f)", + availableWidth, totalOccupiedWidth, width); + remainingCellsMustGoToOverflow = YES; + } + + if (totalOccupiedWidth < availableWidth) { + /* We're not using all available space not but exceeded available width before; * stretch all cells to fully fit the bar */ - NSInteger leftoverWidth = availableWidth - totalOccupiedWidth; - if(leftoverWidth > 0) { - NSInteger q; - for(q = numberOfVisibleCells - 1; q >= 0; q--) { - NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1); - NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition; - [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]]; - leftoverWidth -= desiredAddition; - totalOccupiedWidth += desiredAddition; - } - } - } - } else { - // stretch - distribute leftover room among cells, since we can't add this cell - NSInteger leftoverWidth = availableWidth - totalOccupiedWidth; - NSInteger q; - for(q = i - 1; q >= 0; q--) { - NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1); - NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition; - [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]]; - leftoverWidth -= desiredAddition; - } - - remainingCellsMustGoToOverflow = YES; - } - - // done assigning widths; remaining cells go in overflow menu - if(remainingCellsMustGoToOverflow) { - break; - } - } else { - //We're not using size-to-fit - NSInteger revisedWidth = availableWidth / (i + 1); - if(revisedWidth >= [_control cellMinWidth]) { - NSUInteger q; - totalOccupiedWidth = 0; - - for(q = 0; q < [newWidths count]; q++) { - [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:revisedWidth]]; - totalOccupiedWidth += revisedWidth; - } - // just squeezed this one in... - [newWidths addObject:[NSNumber numberWithDouble:revisedWidth]]; - totalOccupiedWidth += revisedWidth; - numberOfVisibleCells++; - } else { - // couldn't fit that last one... - break; - } - } - } else { - //(totalOccupiedWidth < availableWidth) - numberOfVisibleCells = cellCount; - [newWidths addObject:[NSNumber numberWithDouble:width]]; - totalOccupiedWidth += width; - } - } else { - //lay out vertical tabs - if(currentOrigin + cellRect.size.height <= controlRect.size.height) { - [newWidths addObject:[NSNumber numberWithDouble:currentOrigin]]; - numberOfVisibleCells++; - currentOrigin += cellRect.size.height; - } else { - //out of room, the remaining tabs go into overflow - if([newWidths count] > 0 && controlRect.size.height - currentOrigin < 17) { - [newWidths removeLastObject]; - numberOfVisibleCells--; - } - break; - } - } - } - - //make sure there are at least two items in the horizontal tab bar - if([_control orientation] == PSMTabBarHorizontalOrientation) { - if(numberOfVisibleCells < 2 && [cells count] > 1) { - PSMTabBarCell *cell1 = [cells objectAtIndex:0], *cell2 = [cells objectAtIndex:1]; - NSNumber *cellWidth; - - [newWidths removeAllObjects]; - totalOccupiedWidth = 0; - - cellWidth = [NSNumber numberWithDouble:[cell1 desiredWidthOfCell] < availableWidth * 0.5f ?[cell1 desiredWidthOfCell] : availableWidth * 0.5f]; - [newWidths addObject:cellWidth]; - totalOccupiedWidth += [cellWidth doubleValue]; - - cellWidth = [NSNumber numberWithDouble:[cell2 desiredWidthOfCell] < (availableWidth - totalOccupiedWidth) ?[cell2 desiredWidthOfCell] : (availableWidth - totalOccupiedWidth)]; - [newWidths addObject:cellWidth]; - totalOccupiedWidth += [cellWidth doubleValue]; - - if(totalOccupiedWidth < availableWidth) { - [newWidths replaceObjectAtIndex:0 withObject:[NSNumber numberWithDouble:availableWidth - [cellWidth doubleValue]]]; - } - - numberOfVisibleCells = 2; - } - } - - return newWidths; + NSInteger leftoverWidth = availableWidth - totalOccupiedWidth; + if (leftoverWidth > 0) { + NSInteger q; + for (q = numberOfVisibleCells - 1; q >= 0; q--) { + NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1); + NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition; + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]]; + leftoverWidth -= desiredAddition; + totalOccupiedWidth += desiredAddition; + } + } + } + } else { + // stretch - distribute leftover room among cells, since we can't add this cell + NSInteger leftoverWidth = availableWidth - totalOccupiedWidth; + NSInteger q; + for (q = i - 1; q >= 0; q--) { + NSInteger desiredAddition = (NSInteger)leftoverWidth / (q + 1); + NSInteger newCellWidth = (NSInteger)[[newWidths objectAtIndex:q] doubleValue] + desiredAddition; + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:newCellWidth]]; + leftoverWidth -= desiredAddition; + } + + remainingCellsMustGoToOverflow = YES; + } + + // done assigning widths; remaining cells go in overflow menu + if (remainingCellsMustGoToOverflow) { + break; + } + } else { + //We're not using size-to-fit + NSInteger revisedWidth = availableWidth / (i + 1); + if (revisedWidth >= [_control cellMinWidth]) { + NSUInteger q; + totalOccupiedWidth = 0; + + for (q = 0; q < [newWidths count]; q++) { + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithDouble:revisedWidth]]; + totalOccupiedWidth += revisedWidth; + } + // just squeezed this one in... + [newWidths addObject:[NSNumber numberWithDouble:revisedWidth]]; + totalOccupiedWidth += revisedWidth; + numberOfVisibleCells++; + } else { + // couldn't fit that last one... + break; + } + } + } else { + //(totalOccupiedWidth < availableWidth) + numberOfVisibleCells = cellCount; + [newWidths addObject:[NSNumber numberWithDouble:width]]; + totalOccupiedWidth += width; + } + } else { + //lay out vertical tabs + if (currentOrigin + cellRect.size.height <= controlRect.size.height) { + [newWidths addObject:[NSNumber numberWithDouble:currentOrigin]]; + numberOfVisibleCells++; + currentOrigin += cellRect.size.height; + } else { + //out of room, the remaining tabs go into overflow + if ([newWidths count] > 0 && controlRect.size.height - currentOrigin < 17) { + [newWidths removeLastObject]; + numberOfVisibleCells--; + } + break; + } + } + } + + //make sure there are at least two items in the horizontal tab bar + if ([_control orientation] == PSMTabBarHorizontalOrientation) { + if (numberOfVisibleCells<2 && [cells count]> 1) { + PSMTabBarCell *cell1 = [cells objectAtIndex:0], *cell2 = [cells objectAtIndex:1]; + NSNumber *cellWidth; + + [newWidths removeAllObjects]; + totalOccupiedWidth = 0; + + cellWidth = [NSNumber numberWithDouble:[cell1 desiredWidthOfCell] < availableWidth * 0.5f ? [cell1 desiredWidthOfCell] : availableWidth * 0.5f]; + [newWidths addObject:cellWidth]; + totalOccupiedWidth += [cellWidth doubleValue]; + + cellWidth = [NSNumber numberWithDouble:[cell2 desiredWidthOfCell] < (availableWidth - totalOccupiedWidth) ? [cell2 desiredWidthOfCell] : (availableWidth - totalOccupiedWidth)]; + [newWidths addObject:cellWidth]; + totalOccupiedWidth += [cellWidth doubleValue]; + + if (totalOccupiedWidth < availableWidth) { + [newWidths replaceObjectAtIndex:0 withObject:[NSNumber numberWithDouble:availableWidth - [cellWidth doubleValue]]]; + } + + numberOfVisibleCells = 2; + } + } + + return newWidths; } /*! @@ -494,125 +502,128 @@ static NSInteger potentialMinimumForArray(NSArray *array, NSInteger minimum){ @discussion Creates tracking rect arrays and sets the cells given in the widths array. */ -- (void)_setupCells:(NSArray *)cells withWidths:(NSArray *)widths { - NSUInteger i, tabState, cellCount = [cells count]; - NSRect cellRect = [_control genericCellRect]; - PSMTabBarCell *cell; - NSTabViewItem *selectedTabViewItem = [[_control tabView] selectedTabViewItem]; - NSMenuItem *menuItem; - - _overflowMenu = nil; - - for(i = 0; i < cellCount; i++) { - cell = [cells objectAtIndex:i]; - - if(i < [widths count]) { - tabState = 0; - - // set cell frame - if([_control orientation] == PSMTabBarHorizontalOrientation) { - cellRect.size.width = [[widths objectAtIndex:i] doubleValue]; - } else { - cellRect.size.width = [_control frame].size.width; - cellRect.origin.y = [[widths objectAtIndex:i] doubleValue]; - cellRect.origin.x = 0; - } - - [_cellFrames addObject:[NSValue valueWithRect:cellRect]]; - - //add tracking rects to arrays - [_closeButtonTrackingRects addObject:[NSValue valueWithRect:[cell closeButtonRectForFrame:cellRect]]]; - [_cellTrackingRects addObject:[NSValue valueWithRect:cellRect]]; - - if([[cell representedObject] isEqualTo:selectedTabViewItem]) { - [cell setState:NSOnState]; - tabState |= PSMTab_SelectedMask; - // previous cell - if(i > 0) { - [[cells objectAtIndex:i - 1] setTabState:([(PSMTabBarCell *)[cells objectAtIndex:i - 1] tabState] | PSMTab_RightIsSelectedMask)]; - } - // next cell - see below - } else { - [cell setState:NSOffState]; - // see if prev cell was selected - if((i > 0) && ([[cells objectAtIndex:i - 1] state] == NSOnState)) { - tabState |= PSMTab_LeftIsSelectedMask; - } - } - - // more tab states - if([widths count] == 1) { - tabState |= PSMTab_PositionLeftMask | PSMTab_PositionRightMask | PSMTab_PositionSingleMask; - } else if(i == 0) { - tabState |= PSMTab_PositionLeftMask; - } else if(i == [widths count] - 1) { - tabState |= PSMTab_PositionRightMask; - } - - [cell setTabState:tabState]; - [cell setIsInOverflowMenu:NO]; - - // indicator - if(![[cell indicator] isHidden] && ![_control isTabBarHidden]) { - if(![[_control subviews] containsObject:[cell indicator]]) { - [_control addSubview:[cell indicator]]; - [[cell indicator] startAnimation:self]; - } - } - - // next... - cellRect.origin.x += [[widths objectAtIndex:i] doubleValue]; - } else { - [cell setState:NSOffState]; - [cell setIsInOverflowMenu:YES]; - [[cell indicator] removeFromSuperview]; - - //position the cell well offscreen - if([_control orientation] == PSMTabBarHorizontalOrientation) { - cellRect.origin.x += [[_control style] rightMarginForTabBarControl] + 20; - } else { - cellRect.origin.y = [_control frame].size.height + 2; - } - - [_cellFrames addObject:[NSValue valueWithRect:cellRect]]; - - if(_overflowMenu == nil) { - _overflowMenu = [[NSMenu alloc] init]; - [_overflowMenu insertItemWithTitle:@"" action:nil keyEquivalent:@"" atIndex:0]; // Because the overflowPupUpButton is a pull down menu - [_overflowMenu setDelegate:self]; - } - - // Each item's title is limited to 60 characters. If more than 60 characters, use an ellipsis to indicate that more exists. - menuItem = [_overflowMenu addItemWithTitle:[[[cell attributedStringValue] string] stringWithEllipsisByTruncatingToLength:MAX_OVERFLOW_MENUITEM_TITLE_LENGTH] - action:@selector(overflowMenuAction:) - keyEquivalent:@""]; - [menuItem setTarget:_control]; - [menuItem setRepresentedObject:[cell representedObject]]; - - if([cell count] > 0) { - [menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%lu)", (unsigned long)[cell count]]]; - } - } - } +- (void)_setupCells:(NSArray *)cells withWidths:(NSArray *)widths +{ + NSUInteger i, tabState, cellCount = [cells count]; + NSRect cellRect = [_control genericCellRect]; + PSMTabBarCell *cell; + NSTabViewItem *selectedTabViewItem = [[_control tabView] selectedTabViewItem]; + NSMenuItem *menuItem; + + _overflowMenu = nil; + + for (i = 0; i < cellCount; i++) { + cell = [cells objectAtIndex:i]; + + if (i < [widths count]) { + tabState = 0; + + // set cell frame + if ([_control orientation] == PSMTabBarHorizontalOrientation) { + cellRect.size.width = [[widths objectAtIndex:i] doubleValue]; + } else { + cellRect.size.width = [_control frame].size.width; + cellRect.origin.y = [[widths objectAtIndex:i] doubleValue]; + cellRect.origin.x = 0; + } + + [_cellFrames addObject:[NSValue valueWithRect:cellRect]]; + + //add tracking rects to arrays + [_closeButtonTrackingRects addObject:[NSValue valueWithRect:[cell closeButtonRectForFrame:cellRect]]]; + [_cellTrackingRects addObject:[NSValue valueWithRect:cellRect]]; + + if ([[cell representedObject] isEqualTo:selectedTabViewItem]) { + [cell setState:NSOnState]; + tabState |= PSMTab_SelectedMask; + // previous cell + if (i > 0) { + [[cells objectAtIndex:i - 1] setTabState:([(PSMTabBarCell *)[cells objectAtIndex:i - 1] tabState] | PSMTab_RightIsSelectedMask)]; + } + // next cell - see below + } else { + [cell setState:NSOffState]; + // see if prev cell was selected + if ((i > 0) && ([[cells objectAtIndex:i - 1] state] == NSOnState)) { + tabState |= PSMTab_LeftIsSelectedMask; + } + } + + // more tab states + if ([widths count] == 1) { + tabState |= PSMTab_PositionLeftMask | PSMTab_PositionRightMask | PSMTab_PositionSingleMask; + } else if (i == 0) { + tabState |= PSMTab_PositionLeftMask; + } else if (i == [widths count] - 1) { + tabState |= PSMTab_PositionRightMask; + } + + [cell setTabState:tabState]; + [cell setIsInOverflowMenu:NO]; + + // indicator + if (![[cell indicator] isHidden] && ![_control isTabBarHidden]) { + if (![[_control subviews] containsObject:[cell indicator]]) { + [_control addSubview:[cell indicator]]; + [[cell indicator] startAnimation:self]; + } + } + + // next... + cellRect.origin.x += [[widths objectAtIndex:i] doubleValue]; + } else { + [cell setState:NSOffState]; + [cell setIsInOverflowMenu:YES]; + [[cell indicator] removeFromSuperview]; + + //position the cell well offscreen + if ([_control orientation] == PSMTabBarHorizontalOrientation) { + cellRect.origin.x += [[_control style] rightMarginForTabBarControl] + 20; + } else { + cellRect.origin.y = [_control frame].size.height + 2; + } + + [_cellFrames addObject:[NSValue valueWithRect:cellRect]]; + + if (_overflowMenu == nil) { + _overflowMenu = [[NSMenu alloc] init]; + [_overflowMenu insertItemWithTitle:@"" action:nil keyEquivalent:@"" atIndex:0]; // Because the overflowPupUpButton is a pull down menu + [_overflowMenu setDelegate:self]; + } + + // Each item's title is limited to 60 characters. If more than 60 characters, use an ellipsis to indicate that more exists. + menuItem = [_overflowMenu addItemWithTitle:[[[cell attributedStringValue] string] stringWithEllipsisByTruncatingToLength:MAX_OVERFLOW_MENUITEM_TITLE_LENGTH] + action:@selector(overflowMenuAction:) + keyEquivalent:@""]; + [menuItem setTarget:_control]; + [menuItem setRepresentedObject:[cell representedObject]]; + + if ([cell count] > 0) { + [menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%lu)", (unsigned long)[cell count]]]; + } + } + } } -- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel { - if(menu == _overflowMenu) { - if([[[menuItem representedObject] identifier] respondsToSelector:@selector(icon)]) { - [menuItem setImage:[[[menuItem representedObject] identifier] valueForKey:@"icon"]]; - } - } +- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel +{ + if (menu == _overflowMenu) { + if ([[[menuItem representedObject] identifier] respondsToSelector:@selector(icon)]) { + [menuItem setImage:[[[menuItem representedObject] identifier] valueForKey:@"icon"]]; + } + } - return TRUE; + return TRUE; } -- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu { - if(menu == _overflowMenu) { - return [_overflowMenu numberOfItems]; - } else { - NSLog(@"Warning: Unexpected menu delegate call for menu %@", menu); - return 0; - } +- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu +{ + if (menu == _overflowMenu) { + return [_overflowMenu numberOfItems]; + } else { + NSLog(@"Warning: Unexpected menu delegate call for menu %@", menu); + return 0; + } } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabDragAssistant.m b/frontends/cocoa/PSMTabBarControl/PSMTabDragAssistant.m index 1e3e3684e..0027f8736 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabDragAssistant.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabDragAssistant.m @@ -32,781 +32,819 @@ static PSMTabDragAssistant *sharedDragAssistant = nil; #pragma mark - #pragma mark Creation/Destruction -+ (PSMTabDragAssistant *)sharedDragAssistant { - if(!sharedDragAssistant) { - sharedDragAssistant = [[PSMTabDragAssistant alloc] init]; - } ++ (PSMTabDragAssistant *)sharedDragAssistant +{ + if (!sharedDragAssistant) { + sharedDragAssistant = [[PSMTabDragAssistant alloc] init]; + } - return sharedDragAssistant; + return sharedDragAssistant; } -- (id)init { - if((self = [super init])) { - _sourceTabBar = nil; - _destinationTabBar = nil; - _participatingTabBars = [[NSMutableSet alloc] init]; - _draggedCell = nil; - _animationTimer = nil; - _sineCurveWidths = [[NSMutableArray alloc] initWithCapacity:kPSMTabDragAnimationSteps]; - _targetCell = nil; - _isDragging = NO; - } +- (id)init +{ + if ((self = [super init])) { + _sourceTabBar = nil; + _destinationTabBar = nil; + _participatingTabBars = [[NSMutableSet alloc] init]; + _draggedCell = nil; + _animationTimer = nil; + _sineCurveWidths = [[NSMutableArray alloc] initWithCapacity:kPSMTabDragAnimationSteps]; + _targetCell = nil; + _isDragging = NO; + } - return self; + return self; } - #pragma mark - #pragma mark Accessors -- (PSMTabBarControl *)sourceTabBar { - return _sourceTabBar; +- (PSMTabBarControl *)sourceTabBar +{ + return _sourceTabBar; } -- (void)setSourceTabBar:(PSMTabBarControl *)tabBar { - _sourceTabBar = tabBar; +- (void)setSourceTabBar:(PSMTabBarControl *)tabBar +{ + _sourceTabBar = tabBar; } -- (PSMTabBarControl *)destinationTabBar { - return _destinationTabBar; +- (PSMTabBarControl *)destinationTabBar +{ + return _destinationTabBar; } -- (void)setDestinationTabBar:(PSMTabBarControl *)tabBar { - _destinationTabBar = tabBar; +- (void)setDestinationTabBar:(PSMTabBarControl *)tabBar +{ + _destinationTabBar = tabBar; } -- (PSMTabBarCell *)draggedCell { - return _draggedCell; +- (PSMTabBarCell *)draggedCell +{ + return _draggedCell; } -- (void)setDraggedCell:(PSMTabBarCell *)cell { - _draggedCell = cell; +- (void)setDraggedCell:(PSMTabBarCell *)cell +{ + _draggedCell = cell; } -- (NSInteger)draggedCellIndex { - return _draggedCellIndex; +- (NSInteger)draggedCellIndex +{ + return _draggedCellIndex; } -- (void)setDraggedCellIndex:(NSInteger)value { - _draggedCellIndex = value; +- (void)setDraggedCellIndex:(NSInteger)value +{ + _draggedCellIndex = value; } -- (BOOL)isDragging { - return _isDragging; +- (BOOL)isDragging +{ + return _isDragging; } -- (void)setIsDragging:(BOOL)value { - _isDragging = value; +- (void)setIsDragging:(BOOL)value +{ + _isDragging = value; } -- (NSPoint)currentMouseLoc { - return _currentMouseLoc; +- (NSPoint)currentMouseLoc +{ + return _currentMouseLoc; } -- (void)setCurrentMouseLoc:(NSPoint)point { - _currentMouseLoc = point; +- (void)setCurrentMouseLoc:(NSPoint)point +{ + _currentMouseLoc = point; } -- (PSMTabBarCell *)targetCell { - return _targetCell; +- (PSMTabBarCell *)targetCell +{ + return _targetCell; } -- (void)setTargetCell:(PSMTabBarCell *)cell { - _targetCell = cell; +- (void)setTargetCell:(PSMTabBarCell *)cell +{ + _targetCell = cell; } #pragma mark - #pragma mark Functionality -- (void)startDraggingCell:(PSMTabBarCell *)cell fromTabBar:(PSMTabBarControl *)control withMouseDownEvent:(NSEvent *)event { - [self setIsDragging:YES]; - [self setSourceTabBar:control]; - [self setDestinationTabBar:control]; - [_participatingTabBars addObject:control]; - [self setDraggedCell:cell]; - [self setDraggedCellIndex:[[control cells] indexOfObject:cell]]; - - NSRect cellFrame = [cell frame]; - // list of widths for animation - NSInteger i; - CGFloat cellStepSize = ([control orientation] == PSMTabBarHorizontalOrientation) ? (cellFrame.size.width + 6) : (cellFrame.size.height + 1); - for(i = 0; i < kPSMTabDragAnimationSteps - 1; i++) { - NSInteger thisWidth = (NSInteger)(cellStepSize - ((cellStepSize / 2.0) + ((sin((PI / 2.0) + ((CGFloat)i / (CGFloat)kPSMTabDragAnimationSteps) * PI) * cellStepSize) / 2.0))); - [_sineCurveWidths addObject:[NSNumber numberWithInteger:thisWidth]]; - } - [_sineCurveWidths addObject:[NSNumber numberWithInteger:([control orientation] == PSMTabBarHorizontalOrientation) ? cellFrame.size.width : cellFrame.size.height]]; - - // hide UI buttons - [[control overflowPopUpButton] setHidden:YES]; - [[control addTabButton] setHidden:YES]; - - [[NSCursor closedHandCursor] set]; - - NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - NSImage *dragImage = [cell dragImage]; - [[cell indicator] removeFromSuperview]; - [self distributePlaceholdersInTabBar:control withDraggedCell:cell]; - - if([control isFlipped]) { - cellFrame.origin.y += cellFrame.size.height; - } - [cell setHighlighted:NO]; - NSSize offset = NSZeroSize; - [pboard declareTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil] owner: nil]; - [pboard setString:[[NSNumber numberWithInteger:[[control cells] indexOfObject:cell]] stringValue] forType:@"PSMTabBarControlItemPBType"]; - _animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateDrag:) userInfo:nil repeats:YES]; - - [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidBeginNotification object:nil]; - - //retain the control in case the drag operation causes the control to be released - - if([control delegate] && [[control delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - [[control delegate] tabView:[control tabView] shouldDropTabViewItem:[[self draggedCell] representedObject] inTabBar:nil]) { - _currentTearOffStyle = [control tearOffStyle]; - _draggedTab = [[PSMTabDragWindowController alloc] initWithImage:dragImage styleMask:NSWindowStyleMaskBorderless tearOffStyle:_currentTearOffStyle]; - - cellFrame.origin.y -= cellFrame.size.height; - [control dragImage:[[NSImage alloc] initWithSize:NSMakeSize(1, 1)] at:cellFrame.origin offset:offset event:event pasteboard:pboard source:control slideBack:NO]; - } else { - [control dragImage:dragImage at:cellFrame.origin offset:offset event:event pasteboard:pboard source:control slideBack:YES]; - } - -} - -- (void)draggingEnteredTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc { - if(_currentTearOffStyle == PSMTabBarTearOffMiniwindow && ![self destinationTabBar]) { - [_draggedTab switchImages]; - } - - [self setDestinationTabBar:control]; - [self setCurrentMouseLoc:mouseLoc]; - // hide UI buttons - [[control overflowPopUpButton] setHidden:YES]; - [[control addTabButton] setHidden:YES]; - if([[control cells] count] == 0 || ![[[control cells] objectAtIndex:0] isPlaceholder]) { - [self distributePlaceholdersInTabBar:control]; - } - [_participatingTabBars addObject:control]; - - //tell the drag window to display only the header if there is one - if(_currentTearOffStyle == PSMTabBarTearOffAlphaWindow && _draggedView) { - if(_fadeTimer) { - [_fadeTimer invalidate]; - } - - [[_draggedTab window] orderFront:nil]; - _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeOutDragWindow:) userInfo:nil repeats:YES]; - } -} - -- (void)draggingUpdatedInTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc { - if([self destinationTabBar] != control) { - [self setDestinationTabBar:control]; - } - [self setCurrentMouseLoc:mouseLoc]; -} - -- (void)draggingExitedTabBar:(PSMTabBarControl *)control { - if([[control delegate] respondsToSelector:@selector(tabView:shouldAllowTabViewItem:toLeaveTabBar:)] && - ![[control delegate] tabView:[control tabView] shouldAllowTabViewItem:[[self draggedCell] representedObject] toLeaveTabBar:control]) { - return; - } - - [self setDestinationTabBar:nil]; - [self setCurrentMouseLoc:NSMakePoint(-1.0, -1.0)]; - - if(_fadeTimer) { - [_fadeTimer invalidate]; - _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeInDragWindow:) userInfo:nil repeats:YES]; - } else if(_draggedTab) { - if(_currentTearOffStyle == PSMTabBarTearOffAlphaWindow) { - //create a new floating drag window - if(!_draggedView) { - NSUInteger styleMask; - NSImage *viewImage = [self _imageForViewOfCell:[self draggedCell] styleMask:&styleMask]; - - _draggedView = [[PSMTabDragWindowController alloc] initWithImage:viewImage styleMask:styleMask tearOffStyle:PSMTabBarTearOffAlphaWindow]; - [[_draggedView window] setAlphaValue:0.0]; - } - - NSPoint windowOrigin = [[control window] frame].origin; - - windowOrigin.x -= _dragWindowOffset.width; - windowOrigin.y += _dragWindowOffset.height; - [[_draggedView window] setFrameOrigin:windowOrigin]; - [[_draggedView window] orderWindow:NSWindowBelow relativeTo:[[_draggedTab window] windowNumber]]; - } else if(_currentTearOffStyle == PSMTabBarTearOffMiniwindow && ![_draggedTab alternateImage]) { - NSImage *image; - NSSize imageSize; - NSUInteger mask; //we don't need this but we can't pass nil in for the style mask, as some delegate implementations will crash - - if(!(image = [self _miniwindowImageOfWindow:[control window]])) { - image = [[self _imageForViewOfCell:[self draggedCell] styleMask:&mask] copy]; - } - - imageSize = [image size]; - [image setScalesWhenResized:YES]; - - if(imageSize.width > imageSize.height) { - [image setSize:NSMakeSize(125, 125 * (imageSize.height / imageSize.width))]; - } else { - [image setSize:NSMakeSize(125 * (imageSize.width / imageSize.height), 125)]; - } - - [_draggedTab setAlternateImage:image]; - } - - //set the window's alpha mask to zero if the last tab is being dragged - //don't fade out the old window if the delegate doesn't respond to the new tab bar method, just to be safe - if([[[self sourceTabBar] tabView] numberOfTabViewItems] == 1 && [self sourceTabBar] == control && - [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:newTabBarForDraggedTabViewItem:atPoint:)]) { - [[[self sourceTabBar] window] setAlphaValue:0.0]; - - if([_sourceTabBar tearOffStyle] == PSMTabBarTearOffAlphaWindow) { - [[_draggedView window] setAlphaValue:kPSMTabDragWindowAlpha]; - } else { - //#warning fix me - what should we do when the last tab is dragged as a miniwindow? - } - } else { - if([_sourceTabBar tearOffStyle] == PSMTabBarTearOffAlphaWindow) { - _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeInDragWindow:) userInfo:nil repeats:YES]; - } else { - [_draggedTab switchImages]; - _centersDragWindows = YES; - } - } - } -} - -- (void)performDragOperation { - // move cell - NSUInteger destinationIndex = [[[self destinationTabBar] cells] indexOfObject:[self targetCell]]; - - //there is the slight possibility of the targetCell now being set properly, so avoid errors - if(destinationIndex >= [[[self destinationTabBar] cells] count]) { - destinationIndex = [[[self destinationTabBar] cells] count] - 1; - } - - [[[self destinationTabBar] cells] replaceObjectAtIndex:destinationIndex withObject:[self draggedCell]]; - [[self draggedCell] setControlView:[self destinationTabBar]]; - - // move actual NSTabViewItem - if([self sourceTabBar] != [self destinationTabBar]) { - //remove the tracking rects and bindings registered on the old tab - [[self sourceTabBar] removeTrackingRect:[[self draggedCell] closeButtonTrackingTag]]; - [[self sourceTabBar] removeTrackingRect:[[self draggedCell] cellTrackingTag]]; - [[self sourceTabBar] removeTabForCell:[self draggedCell]]; - - NSUInteger i, insertIndex; - NSArray *cells = [[self destinationTabBar] cells]; - - //find the index of where the dragged cell was just dropped - for(i = 0, insertIndex = 0; (i < [cells count]) && ([cells objectAtIndex:i] != [self draggedCell]); i++, insertIndex++) { - if([[cells objectAtIndex:i] isPlaceholder]) { - insertIndex--; - } - } - - [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; - [[[self destinationTabBar] tabView] insertTabViewItem:[[self draggedCell] representedObject] atIndex:insertIndex]; - - //calculate the position for the dragged cell - if([[self destinationTabBar] automaticallyAnimates]) { - if(insertIndex > 0) { - NSRect cellRect = [[cells objectAtIndex:insertIndex - 1] frame]; - cellRect.origin.x += cellRect.size.width; - [[self draggedCell] setFrame:cellRect]; - } - } - - //rebind the cell to the new control - [[self destinationTabBar] bindPropertiesForCell:[self draggedCell] andTabViewItem:[[self draggedCell] representedObject]]; - - //select the newly moved item in the destination tab view - [[[self destinationTabBar] tabView] selectTabViewItem:[[self draggedCell] representedObject]]; - } else { - //have to do this before checking the index of a cell otherwise placeholders will be counted - [self removeAllPlaceholdersFromTabBar:[self sourceTabBar]]; - - //rearrange the tab view items - NSTabView *tabView = [[self sourceTabBar] tabView]; - NSTabViewItem *item = [[self draggedCell] representedObject]; - BOOL reselect = ([tabView selectedTabViewItem] == item); - NSArray *cells = [[self sourceTabBar] cells]; - NSUInteger index; - //find the index of where the dragged cell was just dropped - for(index = 0; index < [cells count] && [cells objectAtIndex:index] != [self draggedCell]; index++) { - ; - } - - //temporarily disable the delegate in order to move the tab to a different index - id tempDelegate = [tabView delegate]; - [tabView setDelegate:nil]; - [tabView removeTabViewItem:item]; - [tabView insertTabViewItem:item atIndex:index]; - if(reselect) { - [tabView selectTabViewItem:item]; - } - [tabView setDelegate:tempDelegate]; - } - - if(([self sourceTabBar] != [self destinationTabBar] || [[[self sourceTabBar] cells] indexOfObject:[self draggedCell]] != _draggedCellIndex) && [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:didDropTabViewItem:inTabBar:)]) { - [[[self sourceTabBar] delegate] tabView:[[self sourceTabBar] tabView] didDropTabViewItem:[[self draggedCell] representedObject] inTabBar:[self destinationTabBar]]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidEndNotification object:nil]; - - [self finishDrag]; -} - -- (void)draggedImageEndedAt:(NSPoint)aPoint operation:(NSDragOperation)operation { - if([self isDragging]) { // means there was not a successful drop (performDragOperation) - id sourceDelegate = [[self sourceTabBar] delegate]; - - //split off the dragged tab into a new window - if([self destinationTabBar] == nil && - sourceDelegate && [sourceDelegate respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && - [sourceDelegate tabView:[[self sourceTabBar] tabView] shouldDropTabViewItem:[[self draggedCell] representedObject] inTabBar:nil] && - [sourceDelegate respondsToSelector:@selector(tabView:newTabBarForDraggedTabViewItem:atPoint:)]) { - PSMTabBarControl *control = [sourceDelegate tabView:[[self sourceTabBar] tabView] newTabBarForDraggedTabViewItem:[[self draggedCell] representedObject] atPoint:aPoint]; - - if(control) { - //add the dragged tab to the new window - [[control cells] insertObject:[self draggedCell] atIndex:0]; - - //remove the tracking rects and bindings registered on the old tab - [[self sourceTabBar] removeTrackingRect:[[self draggedCell] closeButtonTrackingTag]]; - [[self sourceTabBar] removeTrackingRect:[[self draggedCell] cellTrackingTag]]; - [[self sourceTabBar] removeTabForCell:[self draggedCell]]; - - //rebind the cell to the new control - [control bindPropertiesForCell:[self draggedCell] andTabViewItem:[[self draggedCell] representedObject]]; - - [[self draggedCell] setControlView:control]; - - [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; - - [[control tabView] addTabViewItem:[[self draggedCell] representedObject]]; - [control update:NO]; //make sure the new tab is set in the correct position - - if(_currentTearOffStyle == PSMTabBarTearOffAlphaWindow) { - [[control window] makeKeyAndOrderFront:nil]; - } else { - //center the window over where we ended dragging - [self _expandWindow:[control window] atPoint:[NSEvent mouseLocation]]; - } - - if([sourceDelegate respondsToSelector:@selector(tabView:didDropTabViewItem:inTabBar:)]) { - [sourceDelegate tabView:[[self sourceTabBar] tabView] didDropTabViewItem:[[self draggedCell] representedObject] inTabBar:control]; - } - } else { - NSLog(@"Delegate returned no control to add to."); - [[[self sourceTabBar] cells] insertObject:[self draggedCell] atIndex:[self draggedCellIndex]]; - } - } else { - // put cell back - [[[self sourceTabBar] cells] insertObject:[self draggedCell] atIndex:[self draggedCellIndex]]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidEndNotification object:nil]; - - [self finishDrag]; - } -} - -- (void)finishDrag { - if([[[self sourceTabBar] tabView] numberOfTabViewItems] == 0 && [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:closeWindowForLastTabViewItem:)]) { - [[[self sourceTabBar] delegate] tabView:[[self sourceTabBar] tabView] closeWindowForLastTabViewItem:[[self draggedCell] representedObject]]; - } - - if(_draggedTab) { - [[_draggedTab window] orderOut:nil]; - _draggedTab = nil; - } - - if(_draggedView) { - [[_draggedView window] orderOut:nil]; - _draggedView = nil; - } - - _centersDragWindows = NO; - - [self setIsDragging:NO]; - [self removeAllPlaceholdersFromTabBar:[self sourceTabBar]]; - [self setSourceTabBar:nil]; - [self setDestinationTabBar:nil]; - NSEnumerator *e = [_participatingTabBars objectEnumerator]; - PSMTabBarControl *tabBar; - while((tabBar = [e nextObject])) { - [self removeAllPlaceholdersFromTabBar:tabBar]; - } - [_participatingTabBars removeAllObjects]; - [self setDraggedCell:nil]; - [_animationTimer invalidate]; - _animationTimer = nil; - [_sineCurveWidths removeAllObjects]; - [self setTargetCell:nil]; -} - -- (void)draggingBeganAt:(NSPoint)aPoint { - if(_draggedTab) { - [[_draggedTab window] setFrameTopLeftPoint:aPoint]; - [[_draggedTab window] orderFront:nil]; - - if([[[self sourceTabBar] tabView] numberOfTabViewItems] == 1) { - [self draggingExitedTabBar:[self sourceTabBar]]; - [[_draggedTab window] setAlphaValue:0.0]; - } - } -} - -- (void)draggingMovedTo:(NSPoint)aPoint { - if(_draggedTab) { - if(_centersDragWindows) { - if([_draggedTab isAnimating]) { - return; - } - - //Ignore aPoint, as it seems to give wacky values - NSRect frame = [[_draggedTab window] frame]; - frame.origin = [NSEvent mouseLocation]; - frame.origin.x -= frame.size.width / 2; - frame.origin.y -= frame.size.height / 2; - [[_draggedTab window] setFrame:frame display:NO]; - } else { - [[_draggedTab window] setFrameTopLeftPoint:aPoint]; - } - - if(_draggedView) { - //move the view representation with the tab - //the relative position of the dragged view window will be different - //depending on the position of the tab bar relative to the controlled tab view - - aPoint.y -= [[_draggedTab window] frame].size.height; - aPoint.x -= _dragWindowOffset.width; - aPoint.y += _dragWindowOffset.height; - [[_draggedView window] setFrameTopLeftPoint:aPoint]; - } - } -} - -- (void)fadeInDragWindow:(NSTimer *)timer { - CGFloat value = [[_draggedView window] alphaValue]; - if(value >= kPSMTabDragWindowAlpha || _draggedTab == nil) { - [timer invalidate]; - _fadeTimer = nil; - } else { - [[_draggedTab window] setAlphaValue:[[_draggedTab window] alphaValue] - kPSMTabDragAlphaInterval]; - [[_draggedView window] setAlphaValue:value + kPSMTabDragAlphaInterval]; - } -} - -- (void)fadeOutDragWindow:(NSTimer *)timer { - CGFloat value = [[_draggedView window] alphaValue]; - NSWindow *tabWindow = [_draggedTab window], *viewWindow = [_draggedView window]; - - if(value <= 0.0) { - [viewWindow setAlphaValue:0.0]; - [tabWindow setAlphaValue:kPSMTabDragWindowAlpha]; - - [timer invalidate]; - _fadeTimer = nil; - } else { - if([tabWindow alphaValue] < kPSMTabDragWindowAlpha) { - [tabWindow setAlphaValue:[tabWindow alphaValue] + kPSMTabDragAlphaInterval]; - } - [viewWindow setAlphaValue:value - kPSMTabDragAlphaInterval]; - } +- (void)startDraggingCell:(PSMTabBarCell *)cell fromTabBar:(PSMTabBarControl *)control withMouseDownEvent:(NSEvent *)event +{ + [self setIsDragging:YES]; + [self setSourceTabBar:control]; + [self setDestinationTabBar:control]; + [_participatingTabBars addObject:control]; + [self setDraggedCell:cell]; + [self setDraggedCellIndex:[[control cells] indexOfObject:cell]]; + + NSRect cellFrame = [cell frame]; + // list of widths for animation + NSInteger i; + CGFloat cellStepSize = ([control orientation] == PSMTabBarHorizontalOrientation) ? (cellFrame.size.width + 6) : (cellFrame.size.height + 1); + for (i = 0; i < kPSMTabDragAnimationSteps - 1; i++) { + NSInteger thisWidth = (NSInteger)(cellStepSize - ((cellStepSize / 2.0) + ((sin((PI / 2.0) + ((CGFloat)i / (CGFloat)kPSMTabDragAnimationSteps) * PI) * cellStepSize) / 2.0))); + [_sineCurveWidths addObject:[NSNumber numberWithInteger:thisWidth]]; + } + [_sineCurveWidths addObject:[NSNumber numberWithInteger:([control orientation] == PSMTabBarHorizontalOrientation) ? cellFrame.size.width : cellFrame.size.height]]; + + // hide UI buttons + [[control overflowPopUpButton] setHidden:YES]; + [[control addTabButton] setHidden:YES]; + + [[NSCursor closedHandCursor] set]; + + NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + NSImage *dragImage = [cell dragImage]; + [[cell indicator] removeFromSuperview]; + [self distributePlaceholdersInTabBar:control withDraggedCell:cell]; + + if ([control isFlipped]) { + cellFrame.origin.y += cellFrame.size.height; + } + [cell setHighlighted:NO]; + NSSize offset = NSZeroSize; + [pboard declareTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil] owner:nil]; + [pboard setString:[[NSNumber numberWithInteger:[[control cells] indexOfObject:cell]] stringValue] forType:@"PSMTabBarControlItemPBType"]; + _animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 30.0) target:self selector:@selector(animateDrag:) userInfo:nil repeats:YES]; + + [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidBeginNotification object:nil]; + + //retain the control in case the drag operation causes the control to be released + + if ([control delegate] && [[control delegate] respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && + [[control delegate] tabView:[control tabView] + shouldDropTabViewItem:[[self draggedCell] representedObject] + inTabBar:nil]) { + _currentTearOffStyle = [control tearOffStyle]; + _draggedTab = [[PSMTabDragWindowController alloc] initWithImage:dragImage styleMask:NSWindowStyleMaskBorderless tearOffStyle:_currentTearOffStyle]; + + cellFrame.origin.y -= cellFrame.size.height; + [control dragImage:[[NSImage alloc] initWithSize:NSMakeSize(1, 1)] at:cellFrame.origin offset:offset event:event pasteboard:pboard source:control slideBack:NO]; + } else { + [control dragImage:dragImage at:cellFrame.origin offset:offset event:event pasteboard:pboard source:control slideBack:YES]; + } +} + +- (void)draggingEnteredTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc +{ + if (_currentTearOffStyle == PSMTabBarTearOffMiniwindow && ![self destinationTabBar]) { + [_draggedTab switchImages]; + } + + [self setDestinationTabBar:control]; + [self setCurrentMouseLoc:mouseLoc]; + // hide UI buttons + [[control overflowPopUpButton] setHidden:YES]; + [[control addTabButton] setHidden:YES]; + if ([[control cells] count] == 0 || ![[[control cells] objectAtIndex:0] isPlaceholder]) { + [self distributePlaceholdersInTabBar:control]; + } + [_participatingTabBars addObject:control]; + + //tell the drag window to display only the header if there is one + if (_currentTearOffStyle == PSMTabBarTearOffAlphaWindow && _draggedView) { + if (_fadeTimer) { + [_fadeTimer invalidate]; + } + + [[_draggedTab window] orderFront:nil]; + _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeOutDragWindow:) userInfo:nil repeats:YES]; + } +} + +- (void)draggingUpdatedInTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc +{ + if ([self destinationTabBar] != control) { + [self setDestinationTabBar:control]; + } + [self setCurrentMouseLoc:mouseLoc]; +} + +- (void)draggingExitedTabBar:(PSMTabBarControl *)control +{ + if ([[control delegate] respondsToSelector:@selector(tabView:shouldAllowTabViewItem:toLeaveTabBar:)] && ![[control delegate] tabView:[control tabView] shouldAllowTabViewItem:[[self draggedCell] representedObject] toLeaveTabBar:control]) { + return; + } + + [self setDestinationTabBar:nil]; + [self setCurrentMouseLoc:NSMakePoint(-1.0, -1.0)]; + + if (_fadeTimer) { + [_fadeTimer invalidate]; + _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeInDragWindow:) userInfo:nil repeats:YES]; + } else if (_draggedTab) { + if (_currentTearOffStyle == PSMTabBarTearOffAlphaWindow) { + //create a new floating drag window + if (!_draggedView) { + NSUInteger styleMask; + NSImage *viewImage = [self _imageForViewOfCell:[self draggedCell] styleMask:&styleMask]; + + _draggedView = [[PSMTabDragWindowController alloc] initWithImage:viewImage styleMask:styleMask tearOffStyle:PSMTabBarTearOffAlphaWindow]; + [[_draggedView window] setAlphaValue:0.0]; + } + + NSPoint windowOrigin = [[control window] frame].origin; + + windowOrigin.x -= _dragWindowOffset.width; + windowOrigin.y += _dragWindowOffset.height; + [[_draggedView window] setFrameOrigin:windowOrigin]; + [[_draggedView window] orderWindow:NSWindowBelow relativeTo:[[_draggedTab window] windowNumber]]; + } else if (_currentTearOffStyle == PSMTabBarTearOffMiniwindow && ![_draggedTab alternateImage]) { + NSImage *image; + NSSize imageSize; + NSUInteger mask; //we don't need this but we can't pass nil in for the style mask, as some delegate implementations will crash + + if (!(image = [self _miniwindowImageOfWindow:[control window]])) { + image = [[self _imageForViewOfCell:[self draggedCell] styleMask:&mask] copy]; + } + + imageSize = [image size]; + [image setScalesWhenResized:YES]; + + if (imageSize.width > imageSize.height) { + [image setSize:NSMakeSize(125, 125 * (imageSize.height / imageSize.width))]; + } else { + [image setSize:NSMakeSize(125 * (imageSize.width / imageSize.height), 125)]; + } + + [_draggedTab setAlternateImage:image]; + } + + //set the window's alpha mask to zero if the last tab is being dragged + //don't fade out the old window if the delegate doesn't respond to the new tab bar method, just to be safe + if ([[[self sourceTabBar] tabView] numberOfTabViewItems] == 1 && [self sourceTabBar] == control && + [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:newTabBarForDraggedTabViewItem:atPoint:)]) { + [[[self sourceTabBar] window] setAlphaValue:0.0]; + + if ([_sourceTabBar tearOffStyle] == PSMTabBarTearOffAlphaWindow) { + [[_draggedView window] setAlphaValue:kPSMTabDragWindowAlpha]; + } else { + //#warning fix me - what should we do when the last tab is dragged as a miniwindow? + } + } else { + if ([_sourceTabBar tearOffStyle] == PSMTabBarTearOffAlphaWindow) { + _fadeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(fadeInDragWindow:) userInfo:nil repeats:YES]; + } else { + [_draggedTab switchImages]; + _centersDragWindows = YES; + } + } + } +} + +- (void)performDragOperation +{ + // move cell + NSUInteger destinationIndex = [[[self destinationTabBar] cells] indexOfObject:[self targetCell]]; + + //there is the slight possibility of the targetCell now being set properly, so avoid errors + if (destinationIndex >= [[[self destinationTabBar] cells] count]) { + destinationIndex = [[[self destinationTabBar] cells] count] - 1; + } + + [[[self destinationTabBar] cells] replaceObjectAtIndex:destinationIndex withObject:[self draggedCell]]; + [[self draggedCell] setControlView:[self destinationTabBar]]; + + // move actual NSTabViewItem + if ([self sourceTabBar] != [self destinationTabBar]) { + //remove the tracking rects and bindings registered on the old tab + [[self sourceTabBar] removeTrackingRect:[[self draggedCell] closeButtonTrackingTag]]; + [[self sourceTabBar] removeTrackingRect:[[self draggedCell] cellTrackingTag]]; + [[self sourceTabBar] removeTabForCell:[self draggedCell]]; + + NSUInteger i, insertIndex; + NSArray *cells = [[self destinationTabBar] cells]; + + //find the index of where the dragged cell was just dropped + for (i = 0, insertIndex = 0; (i < [cells count]) && ([cells objectAtIndex:i] != [self draggedCell]); i++, insertIndex++) { + if ([[cells objectAtIndex:i] isPlaceholder]) { + insertIndex--; + } + } + + [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; + [[[self destinationTabBar] tabView] insertTabViewItem:[[self draggedCell] representedObject] atIndex:insertIndex]; + + //calculate the position for the dragged cell + if ([[self destinationTabBar] automaticallyAnimates]) { + if (insertIndex > 0) { + NSRect cellRect = [[cells objectAtIndex:insertIndex - 1] frame]; + cellRect.origin.x += cellRect.size.width; + [[self draggedCell] setFrame:cellRect]; + } + } + + //rebind the cell to the new control + [[self destinationTabBar] bindPropertiesForCell:[self draggedCell] andTabViewItem:[[self draggedCell] representedObject]]; + + //select the newly moved item in the destination tab view + [[[self destinationTabBar] tabView] selectTabViewItem:[[self draggedCell] representedObject]]; + } else { + //have to do this before checking the index of a cell otherwise placeholders will be counted + [self removeAllPlaceholdersFromTabBar:[self sourceTabBar]]; + + //rearrange the tab view items + NSTabView *tabView = [[self sourceTabBar] tabView]; + NSTabViewItem *item = [[self draggedCell] representedObject]; + BOOL reselect = ([tabView selectedTabViewItem] == item); + NSArray *cells = [[self sourceTabBar] cells]; + NSUInteger index; + //find the index of where the dragged cell was just dropped + for (index = 0; index < [cells count] && [cells objectAtIndex:index] != [self draggedCell]; index++) { + ; + } + + //temporarily disable the delegate in order to move the tab to a different index + id tempDelegate = [tabView delegate]; + [tabView setDelegate:nil]; + [tabView removeTabViewItem:item]; + [tabView insertTabViewItem:item atIndex:index]; + if (reselect) { + [tabView selectTabViewItem:item]; + } + [tabView setDelegate:tempDelegate]; + } + + if (([self sourceTabBar] != [self destinationTabBar] || [[[self sourceTabBar] cells] indexOfObject:[self draggedCell]] != _draggedCellIndex) && [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:didDropTabViewItem:inTabBar:)]) { + [[[self sourceTabBar] delegate] tabView:[[self sourceTabBar] tabView] didDropTabViewItem:[[self draggedCell] representedObject] inTabBar:[self destinationTabBar]]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidEndNotification object:nil]; + + [self finishDrag]; +} + +- (void)draggedImageEndedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + if ([self isDragging]) { // means there was not a successful drop (performDragOperation) + id sourceDelegate = [[self sourceTabBar] delegate]; + + //split off the dragged tab into a new window + if ([self destinationTabBar] == nil && sourceDelegate && [sourceDelegate respondsToSelector:@selector(tabView:shouldDropTabViewItem:inTabBar:)] && + [sourceDelegate tabView:[[self sourceTabBar] tabView] + shouldDropTabViewItem:[[self draggedCell] representedObject] + inTabBar:nil] + && + [sourceDelegate respondsToSelector:@selector(tabView:newTabBarForDraggedTabViewItem:atPoint:)]) { + PSMTabBarControl *control = [sourceDelegate tabView:[[self sourceTabBar] tabView] newTabBarForDraggedTabViewItem:[[self draggedCell] representedObject] atPoint:aPoint]; + + if (control) { + //add the dragged tab to the new window + [[control cells] insertObject:[self draggedCell] atIndex:0]; + + //remove the tracking rects and bindings registered on the old tab + [[self sourceTabBar] removeTrackingRect:[[self draggedCell] closeButtonTrackingTag]]; + [[self sourceTabBar] removeTrackingRect:[[self draggedCell] cellTrackingTag]]; + [[self sourceTabBar] removeTabForCell:[self draggedCell]]; + + //rebind the cell to the new control + [control bindPropertiesForCell:[self draggedCell] andTabViewItem:[[self draggedCell] representedObject]]; + + [[self draggedCell] setControlView:control]; + + [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; + + [[control tabView] addTabViewItem:[[self draggedCell] representedObject]]; + [control update:NO]; //make sure the new tab is set in the correct position + + if (_currentTearOffStyle == PSMTabBarTearOffAlphaWindow) { + [[control window] makeKeyAndOrderFront:nil]; + } else { + //center the window over where we ended dragging + [self _expandWindow:[control window] atPoint:[NSEvent mouseLocation]]; + } + + if ([sourceDelegate respondsToSelector:@selector(tabView:didDropTabViewItem:inTabBar:)]) { + [sourceDelegate tabView:[[self sourceTabBar] tabView] didDropTabViewItem:[[self draggedCell] representedObject] inTabBar:control]; + } + } else { + NSLog(@"Delegate returned no control to add to."); + [[[self sourceTabBar] cells] insertObject:[self draggedCell] atIndex:[self draggedCellIndex]]; + } + } else { + // put cell back + [[[self sourceTabBar] cells] insertObject:[self draggedCell] atIndex:[self draggedCellIndex]]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:PSMTabDragDidEndNotification object:nil]; + + [self finishDrag]; + } +} + +- (void)finishDrag +{ + if ([[[self sourceTabBar] tabView] numberOfTabViewItems] == 0 && [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:closeWindowForLastTabViewItem:)]) { + [[[self sourceTabBar] delegate] tabView:[[self sourceTabBar] tabView] closeWindowForLastTabViewItem:[[self draggedCell] representedObject]]; + } + + if (_draggedTab) { + [[_draggedTab window] orderOut:nil]; + _draggedTab = nil; + } + + if (_draggedView) { + [[_draggedView window] orderOut:nil]; + _draggedView = nil; + } + + _centersDragWindows = NO; + + [self setIsDragging:NO]; + [self removeAllPlaceholdersFromTabBar:[self sourceTabBar]]; + [self setSourceTabBar:nil]; + [self setDestinationTabBar:nil]; + NSEnumerator *e = [_participatingTabBars objectEnumerator]; + PSMTabBarControl *tabBar; + while ((tabBar = [e nextObject])) { + [self removeAllPlaceholdersFromTabBar:tabBar]; + } + [_participatingTabBars removeAllObjects]; + [self setDraggedCell:nil]; + [_animationTimer invalidate]; + _animationTimer = nil; + [_sineCurveWidths removeAllObjects]; + [self setTargetCell:nil]; +} + +- (void)draggingBeganAt:(NSPoint)aPoint +{ + if (_draggedTab) { + [[_draggedTab window] setFrameTopLeftPoint:aPoint]; + [[_draggedTab window] orderFront:nil]; + + if ([[[self sourceTabBar] tabView] numberOfTabViewItems] == 1) { + [self draggingExitedTabBar:[self sourceTabBar]]; + [[_draggedTab window] setAlphaValue:0.0]; + } + } +} + +- (void)draggingMovedTo:(NSPoint)aPoint +{ + if (_draggedTab) { + if (_centersDragWindows) { + if ([_draggedTab isAnimating]) { + return; + } + + //Ignore aPoint, as it seems to give wacky values + NSRect frame = [[_draggedTab window] frame]; + frame.origin = [NSEvent mouseLocation]; + frame.origin.x -= frame.size.width / 2; + frame.origin.y -= frame.size.height / 2; + [[_draggedTab window] setFrame:frame display:NO]; + } else { + [[_draggedTab window] setFrameTopLeftPoint:aPoint]; + } + + if (_draggedView) { + //move the view representation with the tab + //the relative position of the dragged view window will be different + //depending on the position of the tab bar relative to the controlled tab view + + aPoint.y -= [[_draggedTab window] frame].size.height; + aPoint.x -= _dragWindowOffset.width; + aPoint.y += _dragWindowOffset.height; + [[_draggedView window] setFrameTopLeftPoint:aPoint]; + } + } +} + +- (void)fadeInDragWindow:(NSTimer *)timer +{ + CGFloat value = [[_draggedView window] alphaValue]; + if (value >= kPSMTabDragWindowAlpha || _draggedTab == nil) { + [timer invalidate]; + _fadeTimer = nil; + } else { + [[_draggedTab window] setAlphaValue:[[_draggedTab window] alphaValue] - kPSMTabDragAlphaInterval]; + [[_draggedView window] setAlphaValue:value + kPSMTabDragAlphaInterval]; + } +} + +- (void)fadeOutDragWindow:(NSTimer *)timer +{ + CGFloat value = [[_draggedView window] alphaValue]; + NSWindow *tabWindow = [_draggedTab window], *viewWindow = [_draggedView window]; + + if (value <= 0.0) { + [viewWindow setAlphaValue:0.0]; + [tabWindow setAlphaValue:kPSMTabDragWindowAlpha]; + + [timer invalidate]; + _fadeTimer = nil; + } else { + if ([tabWindow alphaValue] < kPSMTabDragWindowAlpha) { + [tabWindow setAlphaValue:[tabWindow alphaValue] + kPSMTabDragAlphaInterval]; + } + [viewWindow setAlphaValue:value - kPSMTabDragAlphaInterval]; + } } #pragma mark - #pragma mark Private -- (NSImage *)_imageForViewOfCell:(PSMTabBarCell *)cell styleMask:(NSUInteger *)outMask { - PSMTabBarControl *control = [cell controlView]; - NSImage *viewImage = nil; +- (NSImage *)_imageForViewOfCell:(PSMTabBarCell *)cell styleMask:(NSUInteger *)outMask +{ + PSMTabBarControl *control = [cell controlView]; + NSImage *viewImage = nil; - if(outMask) { - *outMask = NSWindowStyleMaskBorderless; - } + if (outMask) { + *outMask = NSWindowStyleMaskBorderless; + } - if([control delegate] && [[control delegate] respondsToSelector:@selector(tabView:imageForTabViewItem:offset:styleMask:)]) { - //get a custom image representation of the view to drag from the delegate - NSImage *tabImage = [_draggedTab image]; - NSPoint drawPoint; - _dragWindowOffset = NSZeroSize; - viewImage = [[control delegate] tabView:[control tabView] imageForTabViewItem:[cell representedObject] offset:&_dragWindowOffset styleMask:outMask]; - [viewImage lockFocus]; + if ([control delegate] && [[control delegate] respondsToSelector:@selector(tabView:imageForTabViewItem:offset:styleMask:)]) { + //get a custom image representation of the view to drag from the delegate + NSImage *tabImage = [_draggedTab image]; + NSPoint drawPoint; + _dragWindowOffset = NSZeroSize; + viewImage = [[control delegate] tabView:[control tabView] imageForTabViewItem:[cell representedObject] offset:&_dragWindowOffset styleMask:outMask]; + [viewImage lockFocus]; - //draw the tab into the returned window, that way we don't have two windows being dragged (this assumes the tab will be on the window) - drawPoint = NSMakePoint(_dragWindowOffset.width, [viewImage size].height - _dragWindowOffset.height); + //draw the tab into the returned window, that way we don't have two windows being dragged (this assumes the tab will be on the window) + drawPoint = NSMakePoint(_dragWindowOffset.width, [viewImage size].height - _dragWindowOffset.height); - if([control orientation] == PSMTabBarHorizontalOrientation) { - drawPoint.y += [[control style] tabCellHeight] - [tabImage size].height; - _dragWindowOffset.height -= [[control style] tabCellHeight] - [tabImage size].height; - } else { - drawPoint.x += [control frame].size.width - [tabImage size].width; - } + if ([control orientation] == PSMTabBarHorizontalOrientation) { + drawPoint.y += [[control style] tabCellHeight] - [tabImage size].height; + _dragWindowOffset.height -= [[control style] tabCellHeight] - [tabImage size].height; + } else { + drawPoint.x += [control frame].size.width - [tabImage size].width; + } - [tabImage drawAtPoint:drawPoint fromRect: NSZeroRect operation:NSCompositingOperationSourceOver fraction: 1.0]; + [tabImage drawAtPoint:drawPoint fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - [viewImage unlockFocus]; - } else { - //the delegate doesn't give a custom image, so use an image of the view - NSView *tabView = [[cell representedObject] view]; - viewImage = [[NSImage alloc] initWithSize:[tabView frame].size] ; - [viewImage lockFocus]; - [tabView drawRect:[tabView bounds]]; - [viewImage unlockFocus]; - } + [viewImage unlockFocus]; + } else { + //the delegate doesn't give a custom image, so use an image of the view + NSView *tabView = [[cell representedObject] view]; + viewImage = [[NSImage alloc] initWithSize:[tabView frame].size]; + [viewImage lockFocus]; + [tabView drawRect:[tabView bounds]]; + [viewImage unlockFocus]; + } - if(*outMask | NSWindowStyleMaskBorderless) { - _dragWindowOffset.height += 22; - } + if (*outMask | NSWindowStyleMaskBorderless) { + _dragWindowOffset.height += 22; + } - return viewImage; + return viewImage; } -- (NSImage *)_miniwindowImageOfWindow:(NSWindow *)window { - NSRect rect = [window frame]; - NSImage *image = [[NSImage alloc] initWithSize:rect.size] ; - [image lockFocus]; - rect.origin = NSZeroPoint; - CGContextCopyWindowCaptureContentsToRect([[NSGraphicsContext currentContext] graphicsPort], *(CGRect *)&rect, [NSApp contextID], [window windowNumber], 0); - [image unlockFocus]; +- (NSImage *)_miniwindowImageOfWindow:(NSWindow *)window +{ + NSRect rect = [window frame]; + NSImage *image = [[NSImage alloc] initWithSize:rect.size]; + [image lockFocus]; + rect.origin = NSZeroPoint; + CGContextCopyWindowCaptureContentsToRect([[NSGraphicsContext currentContext] graphicsPort], *(CGRect *)&rect, [NSApp contextID], [window windowNumber], 0); + [image unlockFocus]; - return image; + return image; } -- (void)_expandWindow:(NSWindow *)window atPoint:(NSPoint)point { - NSRect frame = [window frame]; - [window setFrameTopLeftPoint:NSMakePoint(point.x - frame.size.width / 2, point.y + frame.size.height / 2)]; - [window setAlphaValue:0.0]; - [window makeKeyAndOrderFront:nil]; +- (void)_expandWindow:(NSWindow *)window atPoint:(NSPoint)point +{ + NSRect frame = [window frame]; + [window setFrameTopLeftPoint:NSMakePoint(point.x - frame.size.width / 2, point.y + frame.size.height / 2)]; + [window setAlphaValue:0.0]; + [window makeKeyAndOrderFront:nil]; - NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.25 animationCurve:NSAnimationEaseInOut]; - [animation setAnimationBlockingMode:NSAnimationNonblocking]; - [animation setCurrentProgress:0.1]; - [animation startAnimation]; - NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(_expandWindowTimerFired:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:window, @"Window", animation, @"Animation", nil] repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; + NSAnimation *animation = [[NSAnimation alloc] initWithDuration:0.25 animationCurve:NSAnimationEaseInOut]; + [animation setAnimationBlockingMode:NSAnimationNonblocking]; + [animation setCurrentProgress:0.1]; + [animation startAnimation]; + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(_expandWindowTimerFired:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:window, @"Window", animation, @"Animation", nil] repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; } -- (void)_expandWindowTimerFired:(NSTimer *)timer { - NSWindow *window = [[timer userInfo] objectForKey:@"Window"]; - NSAnimation *animation = [[timer userInfo] objectForKey:@"Animation"]; - CGAffineTransform transform; - NSPoint translation; - NSRect winFrame = [window frame]; +- (void)_expandWindowTimerFired:(NSTimer *)timer +{ + NSWindow *window = [[timer userInfo] objectForKey:@"Window"]; + NSAnimation *animation = [[timer userInfo] objectForKey:@"Animation"]; + CGAffineTransform transform; + NSPoint translation; + NSRect winFrame = [window frame]; - translation.x = (winFrame.size.width / 2.0); - translation.y = (winFrame.size.height / 2.0); - transform = CGAffineTransformMakeTranslation(translation.x, translation.y); - transform = CGAffineTransformScale(transform, 1.0 / [animation currentValue], 1.0 / [animation currentValue]); - transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); + translation.x = (winFrame.size.width / 2.0); + translation.y = (winFrame.size.height / 2.0); + transform = CGAffineTransformMakeTranslation(translation.x, translation.y); + transform = CGAffineTransformScale(transform, 1.0 / [animation currentValue], 1.0 / [animation currentValue]); + transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); - translation.x = -winFrame.origin.x; - translation.y = winFrame.origin.y + winFrame.size.height - [[NSScreen mainScreen] frame].size.height; + translation.x = -winFrame.origin.x; + translation.y = winFrame.origin.y + winFrame.size.height - [[NSScreen mainScreen] frame].size.height; - transform = CGAffineTransformTranslate(transform, translation.x, translation.y); + transform = CGAffineTransformTranslate(transform, translation.x, translation.y); - CGSSetWindowTransform([NSApp contextID], [window windowNumber], transform); + CGSSetWindowTransform([NSApp contextID], [window windowNumber], transform); - [window setAlphaValue:[animation currentValue]]; + [window setAlphaValue:[animation currentValue]]; - if(![animation isAnimating]) { - [timer invalidate]; - } + if (![animation isAnimating]) { + [timer invalidate]; + } } #pragma mark - #pragma mark Animation -- (void)animateDrag:(NSTimer *)timer { - NSEnumerator *e = [[_participatingTabBars copy] objectEnumerator]; - PSMTabBarControl *tabBar; - while((tabBar = [e nextObject])) { - [self calculateDragAnimationForTabBar:tabBar]; - [[NSRunLoop currentRunLoop] performSelector:@selector(display) target:tabBar argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; - } -} - -- (void)calculateDragAnimationForTabBar:(PSMTabBarControl *)control { - BOOL removeFlag = YES; - NSMutableArray *cells = [control cells]; - NSInteger i, cellCount = [cells count]; - CGFloat position = [control orientation] == PSMTabBarHorizontalOrientation ?[[control style] leftMarginForTabBarControl] :[[control style] topMarginForTabBarControl]; - - // identify target cell - // mouse at beginning of tabs - NSPoint mouseLoc = [self currentMouseLoc]; - if([self destinationTabBar] == control) { - removeFlag = NO; - if(mouseLoc.x < [[control style] leftMarginForTabBarControl]) { - [self setTargetCell:[cells objectAtIndex:0]]; - } else { - NSRect overCellRect; - PSMTabBarCell *overCell = [control cellForPoint:mouseLoc cellFrame:&overCellRect]; - if(overCell) { - // mouse among cells - placeholder - if([overCell isPlaceholder]) { - [self setTargetCell:overCell]; - } else if([control orientation] == PSMTabBarHorizontalOrientation) { - // non-placeholders - horizontal orientation - if(mouseLoc.x < (overCellRect.origin.x + (overCellRect.size.width / 2.0))) { - // mouse on left side of cell - [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] - 1)]]; - } else { - // mouse on right side of cell - [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] + 1)]]; - } - } else { - // non-placeholders - vertical orientation - if(mouseLoc.y < (overCellRect.origin.y + (overCellRect.size.height / 2.0))) { - // mouse on top of cell - [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] - 1)]]; - } else { - // mouse on bottom of cell - [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] + 1)]]; - } - } - } else { - // out at end - must find proper cell (could be more in overflow menu) - [self setTargetCell:[control lastVisibleTab]]; - } - } - } else { - [self setTargetCell:nil]; - } - - for(i = 0; i < cellCount; i++) { - PSMTabBarCell *cell = [cells objectAtIndex:i]; - NSRect newRect = [cell frame]; - if(![cell isInOverflowMenu]) { - if([cell isPlaceholder]) { - if(cell == [self targetCell]) { - [cell setCurrentStep:([cell currentStep] + 1)]; - } else { - [cell setCurrentStep:([cell currentStep] - 1)]; - if([cell currentStep] > 0) { - removeFlag = NO; - } - } - - if([control orientation] == PSMTabBarHorizontalOrientation) { - newRect.size.width = [[_sineCurveWidths objectAtIndex:[cell currentStep]] integerValue]; - } else { - newRect.size.height = [[_sineCurveWidths objectAtIndex:[cell currentStep]] integerValue]; - } - } - } else { - break; - } - - if([control orientation] == PSMTabBarHorizontalOrientation) { - newRect.origin.x = position; - position += newRect.size.width; - } else { - newRect.origin.y = position; - position += newRect.size.height; - } - [cell setFrame:newRect]; - if([cell indicator]) { - [[cell indicator] setFrame:[[control style] indicatorRectForTabCell:cell]]; - } - } - if(removeFlag) { - [_participatingTabBars removeObject:control]; - [self removeAllPlaceholdersFromTabBar:control]; - } +- (void)animateDrag:(NSTimer *)timer +{ + NSEnumerator *e = [[_participatingTabBars copy] objectEnumerator]; + PSMTabBarControl *tabBar; + while ((tabBar = [e nextObject])) { + [self calculateDragAnimationForTabBar:tabBar]; + [[NSRunLoop currentRunLoop] performSelector:@selector(display) target:tabBar argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; + } +} + +- (void)calculateDragAnimationForTabBar:(PSMTabBarControl *)control +{ + BOOL removeFlag = YES; + NSMutableArray *cells = [control cells]; + NSInteger i, cellCount = [cells count]; + CGFloat position = [control orientation] == PSMTabBarHorizontalOrientation ? [[control style] leftMarginForTabBarControl] : [[control style] topMarginForTabBarControl]; + + // identify target cell + // mouse at beginning of tabs + NSPoint mouseLoc = [self currentMouseLoc]; + if ([self destinationTabBar] == control) { + removeFlag = NO; + if (mouseLoc.x < [[control style] leftMarginForTabBarControl]) { + [self setTargetCell:[cells objectAtIndex:0]]; + } else { + NSRect overCellRect; + PSMTabBarCell *overCell = [control cellForPoint:mouseLoc cellFrame:&overCellRect]; + if (overCell) { + // mouse among cells - placeholder + if ([overCell isPlaceholder]) { + [self setTargetCell:overCell]; + } else if ([control orientation] == PSMTabBarHorizontalOrientation) { + // non-placeholders - horizontal orientation + if (mouseLoc.x < (overCellRect.origin.x + (overCellRect.size.width / 2.0))) { + // mouse on left side of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] - 1)]]; + } else { + // mouse on right side of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] + 1)]]; + } + } else { + // non-placeholders - vertical orientation + if (mouseLoc.y < (overCellRect.origin.y + (overCellRect.size.height / 2.0))) { + // mouse on top of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] - 1)]]; + } else { + // mouse on bottom of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] + 1)]]; + } + } + } else { + // out at end - must find proper cell (could be more in overflow menu) + [self setTargetCell:[control lastVisibleTab]]; + } + } + } else { + [self setTargetCell:nil]; + } + + for (i = 0; i < cellCount; i++) { + PSMTabBarCell *cell = [cells objectAtIndex:i]; + NSRect newRect = [cell frame]; + if (![cell isInOverflowMenu]) { + if ([cell isPlaceholder]) { + if (cell == [self targetCell]) { + [cell setCurrentStep:([cell currentStep] + 1)]; + } else { + [cell setCurrentStep:([cell currentStep] - 1)]; + if ([cell currentStep] > 0) { + removeFlag = NO; + } + } + + if ([control orientation] == PSMTabBarHorizontalOrientation) { + newRect.size.width = [[_sineCurveWidths objectAtIndex:[cell currentStep]] integerValue]; + } else { + newRect.size.height = [[_sineCurveWidths objectAtIndex:[cell currentStep]] integerValue]; + } + } + } else { + break; + } + + if ([control orientation] == PSMTabBarHorizontalOrientation) { + newRect.origin.x = position; + position += newRect.size.width; + } else { + newRect.origin.y = position; + position += newRect.size.height; + } + [cell setFrame:newRect]; + if ([cell indicator]) { + [[cell indicator] setFrame:[[control style] indicatorRectForTabCell:cell]]; + } + } + if (removeFlag) { + [_participatingTabBars removeObject:control]; + [self removeAllPlaceholdersFromTabBar:control]; + } } #pragma mark - #pragma mark Placeholders -- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control withDraggedCell:(PSMTabBarCell *)cell { - // called upon first drag - must distribute placeholders - [self distributePlaceholdersInTabBar:control]; - - NSMutableArray *cells = [control cells]; - - // replace dragged cell with a placeholder, and clean up surrounding cells - NSInteger cellIndex = [cells indexOfObject:cell]; - PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:YES inControlView:control] ; - [cells replaceObjectAtIndex:cellIndex withObject:pc]; - [cells removeObjectAtIndex:(cellIndex + 1)]; - [cells removeObjectAtIndex:(cellIndex - 1)]; - - if(cellIndex - 2 >= 0) { - pc = [cells objectAtIndex:cellIndex - 2]; - [pc setTabState:~[pc tabState] & PSMTab_RightIsSelectedMask]; - } -} - -- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control { - NSUInteger i, numVisibleTabs = [control numberOfVisibleTabs]; - for(i = 0; i < numVisibleTabs; i++) { - PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control] ; - [[control cells] insertObject:pc atIndex:(2 * i)]; - } - - PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control] ; - if([[control cells] count] > (2 * numVisibleTabs)) { - [[control cells] insertObject:pc atIndex:(2 * numVisibleTabs)]; - } else { - [[control cells] addObject:pc]; - } -} - -- (void)removeAllPlaceholdersFromTabBar:(PSMTabBarControl *)control { - NSInteger i, cellCount = [[control cells] count]; - for(i = (cellCount - 1); i >= 0; i--) { - PSMTabBarCell *cell = [[control cells] objectAtIndex:i]; - if([cell isPlaceholder]) { - [control removeTabForCell:cell]; - } - } - // redraw - [control update:NO]; +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control withDraggedCell:(PSMTabBarCell *)cell +{ + // called upon first drag - must distribute placeholders + [self distributePlaceholdersInTabBar:control]; + + NSMutableArray *cells = [control cells]; + + // replace dragged cell with a placeholder, and clean up surrounding cells + NSInteger cellIndex = [cells indexOfObject:cell]; + PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:YES inControlView:control]; + [cells replaceObjectAtIndex:cellIndex withObject:pc]; + [cells removeObjectAtIndex:(cellIndex + 1)]; + [cells removeObjectAtIndex:(cellIndex - 1)]; + + if (cellIndex - 2 >= 0) { + pc = [cells objectAtIndex:cellIndex - 2]; + [pc setTabState:~[pc tabState] & PSMTab_RightIsSelectedMask]; + } +} + +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control +{ + NSUInteger i, numVisibleTabs = [control numberOfVisibleTabs]; + for (i = 0; i < numVisibleTabs; i++) { + PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control]; + [[control cells] insertObject:pc atIndex:(2 * i)]; + } + + PSMTabBarCell *pc = [[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control]; + if ([[control cells] count] > (2 * numVisibleTabs)) { + [[control cells] insertObject:pc atIndex:(2 * numVisibleTabs)]; + } else { + [[control cells] addObject:pc]; + } +} + +- (void)removeAllPlaceholdersFromTabBar:(PSMTabBarControl *)control +{ + NSInteger i, cellCount = [[control cells] count]; + for (i = (cellCount - 1); i >= 0; i--) { + PSMTabBarCell *cell = [[control cells] objectAtIndex:i]; + if ([cell isPlaceholder]) { + [control removeTabForCell:cell]; + } + } + // redraw + [control update:NO]; } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - //[super encodeWithCoder:aCoder]; - if([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:_sourceTabBar forKey:@"sourceTabBar"]; - [aCoder encodeObject:_destinationTabBar forKey:@"destinationTabBar"]; - [aCoder encodeObject:_participatingTabBars forKey:@"participatingTabBars"]; - [aCoder encodeObject:_draggedCell forKey:@"draggedCell"]; - [aCoder encodeInteger:_draggedCellIndex forKey:@"draggedCellIndex"]; - [aCoder encodeBool:_isDragging forKey:@"isDragging"]; - [aCoder encodeObject:_animationTimer forKey:@"animationTimer"]; - [aCoder encodeObject:_sineCurveWidths forKey:@"sineCurveWidths"]; - [aCoder encodePoint:_currentMouseLoc forKey:@"currentMouseLoc"]; - [aCoder encodeObject:_targetCell forKey:@"targetCell"]; - } -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - //self = [super initWithCoder:aDecoder]; - //if (self) { - if([aDecoder allowsKeyedCoding]) { - _sourceTabBar = [aDecoder decodeObjectForKey:@"sourceTabBar"] ; - _destinationTabBar = [aDecoder decodeObjectForKey:@"destinationTabBar"] ; - _participatingTabBars = [aDecoder decodeObjectForKey:@"participatingTabBars"] ; - _draggedCell = [aDecoder decodeObjectForKey:@"draggedCell"] ; - _draggedCellIndex = [aDecoder decodeIntegerForKey:@"draggedCellIndex"]; - _isDragging = [aDecoder decodeBoolForKey:@"isDragging"]; - _animationTimer = [aDecoder decodeObjectForKey:@"animationTimer"] ; - _sineCurveWidths = [aDecoder decodeObjectForKey:@"sineCurveWidths"] ; - _currentMouseLoc = [aDecoder decodePointForKey:@"currentMouseLoc"]; - _targetCell = [aDecoder decodeObjectForKey:@"targetCell"] ; - } - //} - return self; +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_sourceTabBar forKey:@"sourceTabBar"]; + [aCoder encodeObject:_destinationTabBar forKey:@"destinationTabBar"]; + [aCoder encodeObject:_participatingTabBars forKey:@"participatingTabBars"]; + [aCoder encodeObject:_draggedCell forKey:@"draggedCell"]; + [aCoder encodeInteger:_draggedCellIndex forKey:@"draggedCellIndex"]; + [aCoder encodeBool:_isDragging forKey:@"isDragging"]; + [aCoder encodeObject:_animationTimer forKey:@"animationTimer"]; + [aCoder encodeObject:_sineCurveWidths forKey:@"sineCurveWidths"]; + [aCoder encodePoint:_currentMouseLoc forKey:@"currentMouseLoc"]; + [aCoder encodeObject:_targetCell forKey:@"targetCell"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + //self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + _sourceTabBar = [aDecoder decodeObjectForKey:@"sourceTabBar"]; + _destinationTabBar = [aDecoder decodeObjectForKey:@"destinationTabBar"]; + _participatingTabBars = [aDecoder decodeObjectForKey:@"participatingTabBars"]; + _draggedCell = [aDecoder decodeObjectForKey:@"draggedCell"]; + _draggedCellIndex = [aDecoder decodeIntegerForKey:@"draggedCellIndex"]; + _isDragging = [aDecoder decodeBoolForKey:@"isDragging"]; + _animationTimer = [aDecoder decodeObjectForKey:@"animationTimer"]; + _sineCurveWidths = [aDecoder decodeObjectForKey:@"sineCurveWidths"]; + _currentMouseLoc = [aDecoder decodePointForKey:@"currentMouseLoc"]; + _targetCell = [aDecoder decodeObjectForKey:@"targetCell"]; + } + //} + return self; } - @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabDragView.m b/frontends/cocoa/PSMTabBarControl/PSMTabDragView.m index 8f901646c..4f6ce9131 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabDragView.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabDragView.m @@ -8,46 +8,52 @@ #import "PSMTabDragView.h" - @implementation PSMTabDragView -- (id)initWithFrame:(NSRect)frame { - if((self = [super initWithFrame:frame])) { - _alpha = 1.0; - } - return self; +- (id)initWithFrame:(NSRect)frame +{ + if ((self = [super initWithFrame:frame])) { + _alpha = 1.0; + } + return self; } -- (void)drawRect:(NSRect)rect { - //1.0 fade means show the primary image - //0.0 fade means show the secondary image - CGFloat primaryAlpha = _alpha + 0.001f, alternateAlpha = 1.001f - _alpha; - NSRect srcRect; - srcRect.origin = NSZeroPoint; - srcRect.size = [_image size]; - - [_image drawInRect:[self bounds] fromRect:srcRect operation:NSCompositingOperationSourceOver fraction:primaryAlpha]; - srcRect.size = [_alternateImage size]; - [_alternateImage drawInRect:[self bounds] fromRect:srcRect operation:NSCompositingOperationSourceOver fraction:alternateAlpha]; +- (void)drawRect:(NSRect)rect +{ + //1.0 fade means show the primary image + //0.0 fade means show the secondary image + CGFloat primaryAlpha = _alpha + 0.001f, alternateAlpha = 1.001f - _alpha; + NSRect srcRect; + srcRect.origin = NSZeroPoint; + srcRect.size = [_image size]; + + [_image drawInRect:[self bounds] fromRect:srcRect operation:NSCompositingOperationSourceOver fraction:primaryAlpha]; + srcRect.size = [_alternateImage size]; + [_alternateImage drawInRect:[self bounds] fromRect:srcRect operation:NSCompositingOperationSourceOver fraction:alternateAlpha]; } -- (void)setFadeValue:(CGFloat)value { - _alpha = value; +- (void)setFadeValue:(CGFloat)value +{ + _alpha = value; } -- (NSImage *)image { - return _image; +- (NSImage *)image +{ + return _image; } -- (void)setImage:(NSImage *)image { +- (void)setImage:(NSImage *)image +{ _image = image; } -- (NSImage *)alternateImage { - return _alternateImage; +- (NSImage *)alternateImage +{ + return _alternateImage; } -- (void)setAlternateImage:(NSImage *)image { +- (void)setAlternateImage:(NSImage *)image +{ _alternateImage = image; } diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabDragWindow.m b/frontends/cocoa/PSMTabBarControl/PSMTabDragWindow.m index 8bf51f6dd..cae9280f1 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabDragWindow.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabDragWindow.m @@ -11,38 +11,41 @@ @implementation PSMTabDragWindow -+ (PSMTabDragWindow *)dragWindowWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask { - return [[PSMTabDragWindow alloc] initWithImage:image styleMask:styleMask] ; ++ (PSMTabDragWindow *)dragWindowWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask +{ + return [[PSMTabDragWindow alloc] initWithImage:image styleMask:styleMask]; } -- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask { - NSSize size = [image size]; +- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask +{ + NSSize size = [image size]; - if((self = [super initWithContentRect:NSMakeRect(0, 0, size.width, size.height) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO])) { - _dragView = [[PSMTabDragView alloc] initWithFrame:NSMakeRect(0, 0, size.width, size.height)] ; - [self setContentView:_dragView]; - [self setLevel:NSStatusWindowLevel]; - [self setIgnoresMouseEvents:YES]; - [self setOpaque:NO]; + if ((self = [super initWithContentRect:NSMakeRect(0, 0, size.width, size.height) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO])) { + _dragView = [[PSMTabDragView alloc] initWithFrame:NSMakeRect(0, 0, size.width, size.height)]; + [self setContentView:_dragView]; + [self setLevel:NSStatusWindowLevel]; + [self setIgnoresMouseEvents:YES]; + [self setOpaque:NO]; - [_dragView setImage:image]; + [_dragView setImage:image]; - //Set the size of the window to be the exact size of the drag image - NSRect windowFrame = [self frame]; - windowFrame.origin.y += windowFrame.size.height - size.height; - windowFrame.size = size; + //Set the size of the window to be the exact size of the drag image + NSRect windowFrame = [self frame]; + windowFrame.origin.y += windowFrame.size.height - size.height; + windowFrame.size = size; - if(styleMask | NSWindowStyleMaskBorderless) { - windowFrame.size.height += 22; - } + if (styleMask | NSWindowStyleMaskBorderless) { + windowFrame.size.height += 22; + } - [self setFrame:windowFrame display:YES]; - } - return self; + [self setFrame:windowFrame display:YES]; + } + return self; } -- (PSMTabDragView *)dragView { - return _dragView; +- (PSMTabDragView *)dragView +{ + return _dragView; } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMTabDragWindowController.m b/frontends/cocoa/PSMTabBarControl/PSMTabDragWindowController.m index 59e52deb7..78b0fcb2c 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMTabDragWindowController.m +++ b/frontends/cocoa/PSMTabBarControl/PSMTabDragWindowController.m @@ -12,91 +12,98 @@ @implementation PSMTabDragWindowController -- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask tearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle { - PSMTabDragWindow *window = [PSMTabDragWindow dragWindowWithImage:image styleMask:styleMask]; - if((self = [super initWithWindow:window])) { - _view = [window dragView] ; - _tearOffStyle = tearOffStyle; - - if(tearOffStyle == PSMTabBarTearOffMiniwindow) { - [window setBackgroundColor:[NSColor clearColor]]; - [window setHasShadow:YES]; - } - - [window setAlphaValue:kPSMTabDragWindowAlpha]; - } - return self; +- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask tearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle +{ + PSMTabDragWindow *window = [PSMTabDragWindow dragWindowWithImage:image styleMask:styleMask]; + if ((self = [super initWithWindow:window])) { + _view = [window dragView]; + _tearOffStyle = tearOffStyle; + + if (tearOffStyle == PSMTabBarTearOffMiniwindow) { + [window setBackgroundColor:[NSColor clearColor]]; + [window setHasShadow:YES]; + } + + [window setAlphaValue:kPSMTabDragWindowAlpha]; + } + return self; } -- (void)dealloc { - [_timer invalidate]; - +- (void)dealloc +{ + [_timer invalidate]; } -- (NSImage *)image { - return [_view image]; +- (NSImage *)image +{ + return [_view image]; } -- (NSImage *)alternateImage { - return [_view alternateImage]; +- (NSImage *)alternateImage +{ + return [_view alternateImage]; } -- (void)setAlternateImage:(NSImage *)image { - [_view setAlternateImage:image]; +- (void)setAlternateImage:(NSImage *)image +{ + [_view setAlternateImage:image]; } -- (BOOL)isAnimating { - return _animation != nil; +- (BOOL)isAnimating +{ + return _animation != nil; } -- (void)switchImages { - if(_tearOffStyle != PSMTabBarTearOffMiniwindow || ![_view alternateImage]) { - return; - } - - CGFloat progress = 0; - _showingAlternate = !_showingAlternate; - - if(_animation) { - //An animation already exists, get the current progress - progress = 1.0f - [_animation currentProgress]; - [_animation stopAnimation]; - } - - //begin animating - _animation = [[NSAnimation alloc] initWithDuration:0.25 animationCurve:NSAnimationEaseInOut]; - [_animation setAnimationBlockingMode:NSAnimationNonblocking]; - [_animation setCurrentProgress:progress]; - [_animation startAnimation]; - - _originalWindowFrame = [[self window] frame]; - - if(_timer) { - [_timer invalidate]; - } - _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f / 30.0f target:self selector:@selector(animateTimer:) userInfo:nil repeats:YES]; +- (void)switchImages +{ + if (_tearOffStyle != PSMTabBarTearOffMiniwindow || ![_view alternateImage]) { + return; + } + + CGFloat progress = 0; + _showingAlternate = !_showingAlternate; + + if (_animation) { + //An animation already exists, get the current progress + progress = 1.0f - [_animation currentProgress]; + [_animation stopAnimation]; + } + + //begin animating + _animation = [[NSAnimation alloc] initWithDuration:0.25 animationCurve:NSAnimationEaseInOut]; + [_animation setAnimationBlockingMode:NSAnimationNonblocking]; + [_animation setCurrentProgress:progress]; + [_animation startAnimation]; + + _originalWindowFrame = [[self window] frame]; + + if (_timer) { + [_timer invalidate]; + } + _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f / 30.0f target:self selector:@selector(animateTimer:) userInfo:nil repeats:YES]; } -- (void)animateTimer:(NSTimer *)timer { - NSRect frame = _originalWindowFrame; - NSImage *currentImage = _showingAlternate ?[_view alternateImage] :[_view image]; - NSSize size = [currentImage size]; - NSPoint mousePoint = [NSEvent mouseLocation]; - CGFloat animationValue = [_animation currentValue]; - - frame.size.width = _originalWindowFrame.size.width + (size.width - _originalWindowFrame.size.width) * animationValue; - frame.size.height = _originalWindowFrame.size.height + (size.height - _originalWindowFrame.size.height) * animationValue; - frame.origin.x = mousePoint.x - (frame.size.width / 2); - frame.origin.y = mousePoint.y - (frame.size.height / 2); - - [_view setFadeValue:_showingAlternate ? 1.0f - animationValue : animationValue]; - [[self window] setFrame:frame display:YES]; - - if(![_animation isAnimating]) { - _animation = nil; - [timer invalidate]; - _timer = nil; - } +- (void)animateTimer:(NSTimer *)timer +{ + NSRect frame = _originalWindowFrame; + NSImage *currentImage = _showingAlternate ? [_view alternateImage] : [_view image]; + NSSize size = [currentImage size]; + NSPoint mousePoint = [NSEvent mouseLocation]; + CGFloat animationValue = [_animation currentValue]; + + frame.size.width = _originalWindowFrame.size.width + (size.width - _originalWindowFrame.size.width) * animationValue; + frame.size.height = _originalWindowFrame.size.height + (size.height - _originalWindowFrame.size.height) * animationValue; + frame.origin.x = mousePoint.x - (frame.size.width / 2); + frame.origin.y = mousePoint.y - (frame.size.height / 2); + + [_view setFadeValue:_showingAlternate ? 1.0f - animationValue : animationValue]; + [[self window] setFrame:frame display:YES]; + + if (![_animation isAnimating]) { + _animation = nil; + [timer invalidate]; + _timer = nil; + } } @end diff --git a/frontends/cocoa/PSMTabBarControl/PSMUnifiedTabStyle.m b/frontends/cocoa/PSMTabBarControl/PSMUnifiedTabStyle.m index 98bf6c1e4..687c7792c 100644 --- a/frontends/cocoa/PSMTabBarControl/PSMUnifiedTabStyle.m +++ b/frontends/cocoa/PSMTabBarControl/PSMUnifiedTabStyle.m @@ -15,544 +15,567 @@ #define kPSMUnifiedCounterMinWidth 20 @interface PSMUnifiedTabStyle (Private) -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView *)controlView; @end @implementation PSMUnifiedTabStyle -- (NSString *)name { - return @"Unified"; +- (NSString *)name +{ + return @"Unified"; } #pragma mark - #pragma mark Creation/Destruction -- (id) init { - if((self = [super init])) { - unifiedCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; - unifiedCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; - unifiedCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; +- (id)init +{ + if ((self = [super init])) { + unifiedCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; + unifiedCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; + unifiedCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; - unifiedCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; - unifiedCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; - unifiedCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; + unifiedCloseDirtyButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front"]]; + unifiedCloseDirtyButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Pressed"]]; + unifiedCloseDirtyButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabCloseDirty_Front_Rollover"]]; - _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; - _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; - _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; + _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; + _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; + _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; - _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, - [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, - nil, nil]; + _objectCountStringAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask], NSFontAttributeName, + [[NSColor whiteColor] colorWithAlphaComponent:0.85], NSForegroundColorAttributeName, + nil, nil]; - leftMargin = 5.0; - } - return self; + leftMargin = 5.0; + } + return self; } - #pragma mark - #pragma mark Control Specific -- (void)setLeftMarginForTabBarControl:(CGFloat)margin { - leftMargin = margin; +- (void)setLeftMarginForTabBarControl:(CGFloat)margin +{ + leftMargin = margin; } -- (CGFloat)leftMarginForTabBarControl { - return leftMargin; +- (CGFloat)leftMarginForTabBarControl +{ + return leftMargin; } -- (CGFloat)rightMarginForTabBarControl { - return 24.0f; +- (CGFloat)rightMarginForTabBarControl +{ + return 24.0f; } -- (CGFloat)topMarginForTabBarControl { - return 10.0f; +- (CGFloat)topMarginForTabBarControl +{ + return 10.0f; } -- (void)setOrientation:(PSMTabBarOrientation)value { +- (void)setOrientation:(PSMTabBarOrientation)value +{ } #pragma mark - #pragma mark Add Tab Button -- (NSImage *)addTabButtonImage { - return _addTabButtonImage; +- (NSImage *)addTabButtonImage +{ + return _addTabButtonImage; } -- (NSImage *)addTabButtonPressedImage { - return _addTabButtonPressedImage; +- (NSImage *)addTabButtonPressedImage +{ + return _addTabButtonPressedImage; } -- (NSImage *)addTabButtonRolloverImage { - return _addTabButtonRolloverImage; +- (NSImage *)addTabButtonRolloverImage +{ + return _addTabButtonRolloverImage; } #pragma mark - #pragma mark Cell Specific -- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)orientation { - NSRect dragRect = [cell frame]; - dragRect.size.width++; - return dragRect; +- (NSRect)dragRectForTabCell:(PSMTabBarCell *)cell orientation:(PSMTabBarOrientation)orientation +{ + NSRect dragRect = [cell frame]; + dragRect.size.width++; + return dragRect; } -- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame { - if([cell hasCloseButton] == NO) { - return NSZeroRect; - } +- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell withFrame:(NSRect)cellFrame +{ + if ([cell hasCloseButton] == NO) { + return NSZeroRect; + } - NSRect result; - result.size = [unifiedCloseButton size]; - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + NSRect result; + result.size = [unifiedCloseButton size]; + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - return result; + return result; } -- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell { - NSRect cellFrame = [cell frame]; +- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; - if([cell hasIcon] == NO) { - return NSZeroRect; - } + if ([cell hasIcon] == NO) { + return NSZeroRect; + } - NSRect result; - result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); - result.origin.x = cellFrame.origin.x + MARGIN_X; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; + NSRect result; + result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - result.origin.x += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + result.origin.x += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + } - return result; + return result; } -- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell { - NSRect cellFrame = [cell frame]; +- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; - if([[cell indicator] isHidden]) { - return NSZeroRect; - } + if ([[cell indicator] isHidden]) { + return NSZeroRect; + } - NSRect result; - result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; - result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; + NSRect result; + result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; + result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; - return result; + return result; } -- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell { - NSRect cellFrame = [cell frame]; +- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; - if([cell count] == 0) { - return NSZeroRect; - } + if ([cell count] == 0) { + return NSZeroRect; + } - CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; - countWidth += (2 * kPSMUnifiedObjectCounterRadius - 6.0); - if(countWidth < kPSMUnifiedCounterMinWidth) { - countWidth = kPSMUnifiedCounterMinWidth; - } + CGFloat countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; + countWidth += (2 * kPSMUnifiedObjectCounterRadius - 6.0); + if (countWidth < kPSMUnifiedCounterMinWidth) { + countWidth = kPSMUnifiedCounterMinWidth; + } - NSRect result; - result.size = NSMakeSize(countWidth, 2 * kPSMUnifiedObjectCounterRadius); // temp - result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; - result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + NSRect result; + result.size = NSMakeSize(countWidth, 2 * kPSMUnifiedObjectCounterRadius); // temp + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; - if(![[cell indicator] isHidden]) { - result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; - } + if (![[cell indicator] isHidden]) { + result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; + } - return result; + return result; } +- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell +{ + CGFloat resultWidth = 0.0; -- (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell { - CGFloat resultWidth = 0.0; - - // left margin - resultWidth = MARGIN_X; + // left margin + resultWidth = MARGIN_X; - // close button? - if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + } - // icon? - if([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } + // icon? + if ([cell hasIcon]) { + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + } - // the label - resultWidth += kPSMMinimumTitleWidth; + // the label + resultWidth += kPSMMinimumTitleWidth; - // object counter? - if([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } + // object counter? + if ([cell count] > 0) { + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + } - // indicator? - if([[cell indicator] isHidden] == NO) { - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - } + // indicator? + if ([[cell indicator] isHidden] == NO) { + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + } - // right margin - resultWidth += MARGIN_X; + // right margin + resultWidth += MARGIN_X; - return ceil(resultWidth); + return ceil(resultWidth); } -- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell { - CGFloat resultWidth = 0.0; +- (CGFloat)desiredWidthOfTabCell:(PSMTabBarCell *)cell +{ + CGFloat resultWidth = 0.0; - // left margin - resultWidth = MARGIN_X; + // left margin + resultWidth = MARGIN_X; - // close button? - if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; - } + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + } - // icon? - if([cell hasIcon]) { - resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; - } + // icon? + if ([cell hasIcon]) { + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + } - // the label - resultWidth += [[cell attributedStringValue] size].width; + // the label + resultWidth += [[cell attributedStringValue] size].width; - // object counter? - if([cell count] > 0) { - resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; - } + // object counter? + if ([cell count] > 0) { + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + } - // indicator? - if([[cell indicator] isHidden] == NO) { - resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; - } + // indicator? + if ([[cell indicator] isHidden] == NO) { + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + } - // right margin - resultWidth += MARGIN_X; + // right margin + resultWidth += MARGIN_X; - return ceil(resultWidth); + return ceil(resultWidth); } -- (CGFloat)tabCellHeight { - return kPSMTabBarControlHeight; +- (CGFloat)tabCellHeight +{ + return kPSMTabBarControlHeight; } #pragma mark - #pragma mark Cell Values -- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell { - NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; - return [[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes] ; +- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell +{ + NSString *contents = [NSString stringWithFormat:@"%lu", (unsigned long)[cell count]]; + return [[NSMutableAttributedString alloc] initWithString:contents attributes:_objectCountStringAttributes]; } -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell { - NSMutableAttributedString *attrStr; - NSString * contents = [cell stringValue]; - attrStr = [[NSMutableAttributedString alloc] initWithString:contents] ; - NSRange range = NSMakeRange(0, [contents length]); +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSString *contents = [cell stringValue]; + attrStr = [[NSMutableAttributedString alloc] initWithString:contents]; + NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - // Paragraph Style for Truncating Long Text - static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; - if(!TruncatingTailParagraphStyle) { - TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy] ; - [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; + // Paragraph Style for Truncating Long Text + static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; + if (!TruncatingTailParagraphStyle) { + TruncatingTailParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; - return attrStr; + return attrStr; } #pragma mark - -#pragma mark ---- drawing ---- - -- (void)drawTabCell:(PSMTabBarCell *)cell { - NSRect cellFrame = [cell frame]; - - NSToolbar *toolbar = [[[cell controlView] window] toolbar]; - BOOL showsBaselineSeparator = (toolbar && [toolbar respondsToSelector:@selector(showsBaselineSeparator)] && [toolbar showsBaselineSeparator]); - if(!showsBaselineSeparator) { - cellFrame.origin.y += 1.0; - cellFrame.size.height -= 1.0; - } - - NSColor * lineColor = nil; - NSBezierPath* bezier = [NSBezierPath bezierPath]; - lineColor = [NSColor colorWithCalibratedWhite:0.576 alpha:1.0]; - - if(!showsBaselineSeparator || [cell state] == NSOnState) { - // selected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x + 0.5, cellFrame.origin.y - 0.5, cellFrame.size.width, cellFrame.size.height); - - // frame - CGFloat radius = MIN(6.0, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect))); - NSRect rect = NSInsetRect(aRect, radius, radius); - - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(rect), NSMinY(rect)) radius:radius startAngle:180.0 endAngle:270.0]; - - [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(rect), NSMinY(rect)) radius:radius startAngle:270.0 endAngle:360.0]; - - NSPoint cornerPoint = NSMakePoint(NSMaxX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - cornerPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect)); - [bezier appendBezierPathWithPoints:&cornerPoint count:1]; - - [bezier closePath]; - - //[[NSColor windowBackgroundColor] set]; - //[bezier fill]; - if([NSApp isActive]) { - if([cell state] == NSOnState) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.99 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.941 alpha:1.0]]; - } else if([cell isHighlighted]) { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0]]; - } else { - [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - } - } - - [lineColor set]; - [bezier stroke]; - } else{ - // unselected tab - NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); - aRect.origin.y += 0.5; - aRect.origin.x += 1.5; - aRect.size.width -= 1; - - aRect.origin.x -= 1; - aRect.size.width += 1; - - // rollover - if([cell isHighlighted]) { - [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; - NSRectFillUsingOperation(aRect, NSCompositingOperationSourceAtop); - } - - // frame - - [lineColor set]; - [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y - 0.5)]; - if(!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; - } - - [bezier stroke]; - - // Create a thin lighter line next to the dividing line for a bezel effect - if(!([cell tabState] & PSMTab_RightIsSelectedMask)) { - [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(aRect) + 1.0, aRect.origin.y - 0.5) - toPoint:NSMakePoint(NSMaxX(aRect) + 1.0, NSMaxY(aRect) - 2.5)]; - } - - // If this is the leftmost tab, we want to draw a line on the left, too - if([cell tabState] & PSMTab_PositionLeftMask) { - [lineColor set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x, aRect.origin.y - 0.5) - toPoint:NSMakePoint(aRect.origin.x, NSMaxY(aRect) - 2.5)]; - [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x + 1.0, aRect.origin.y - 0.5) - toPoint:NSMakePoint(aRect.origin.x + 1.0, NSMaxY(aRect) - 2.5)]; - } - } - - [self drawInteriorWithTabCell:cell inView:[cell controlView]]; +#pragma mark---- drawing ---- + +- (void)drawTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + NSToolbar *toolbar = [[[cell controlView] window] toolbar]; + BOOL showsBaselineSeparator = (toolbar && [toolbar respondsToSelector:@selector(showsBaselineSeparator)] && [toolbar showsBaselineSeparator]); + if (!showsBaselineSeparator) { + cellFrame.origin.y += 1.0; + cellFrame.size.height -= 1.0; + } + + NSColor *lineColor = nil; + NSBezierPath *bezier = [NSBezierPath bezierPath]; + lineColor = [NSColor colorWithCalibratedWhite:0.576 alpha:1.0]; + + if (!showsBaselineSeparator || [cell state] == NSOnState) { + // selected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x + 0.5, cellFrame.origin.y - 0.5, cellFrame.size.width, cellFrame.size.height); + + // frame + CGFloat radius = MIN(6.0, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect))); + NSRect rect = NSInsetRect(aRect, radius, radius); + + [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(rect), NSMinY(rect)) radius:radius startAngle:180.0 endAngle:270.0]; + + [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(rect), NSMinY(rect)) radius:radius startAngle:270.0 endAngle:360.0]; + + NSPoint cornerPoint = NSMakePoint(NSMaxX(aRect), NSMaxY(aRect)); + [bezier appendBezierPathWithPoints:&cornerPoint count:1]; + + cornerPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect)); + [bezier appendBezierPathWithPoints:&cornerPoint count:1]; + + [bezier closePath]; + + //[[NSColor windowBackgroundColor] set]; + //[bezier fill]; + if ([NSApp isActive]) { + if ([cell state] == NSOnState) { + [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.99 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.941 alpha:1.0]]; + } else if ([cell isHighlighted]) { + [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.80 alpha:1.0]]; + } else { + [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; + } + } + + [lineColor set]; + [bezier stroke]; + } else { + // unselected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); + aRect.origin.y += 0.5; + aRect.origin.x += 1.5; + aRect.size.width -= 1; + + aRect.origin.x -= 1; + aRect.size.width += 1; + + // rollover + if ([cell isHighlighted]) { + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; + NSRectFillUsingOperation(aRect, NSCompositingOperationSourceAtop); + } + + // frame + + [lineColor set]; + [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y - 0.5)]; + if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { + [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; + } + + [bezier stroke]; + + // Create a thin lighter line next to the dividing line for a bezel effect + if (!([cell tabState] & PSMTab_RightIsSelectedMask)) { + [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(aRect) + 1.0, aRect.origin.y - 0.5) + toPoint:NSMakePoint(NSMaxX(aRect) + 1.0, NSMaxY(aRect) - 2.5)]; + } + + // If this is the leftmost tab, we want to draw a line on the left, too + if ([cell tabState] & PSMTab_PositionLeftMask) { + [lineColor set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x, aRect.origin.y - 0.5) + toPoint:NSMakePoint(aRect.origin.x, NSMaxY(aRect) - 2.5)]; + [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x + 1.0, aRect.origin.y - 0.5) + toPoint:NSMakePoint(aRect.origin.x + 1.0, NSMaxY(aRect) - 2.5)]; + } + } + + [self drawInteriorWithTabCell:cell inView:[cell controlView]]; } - -- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView { - NSRect cellFrame = [cell frame]; - CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; - - // close button - if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { - NSSize closeButtonSize = NSZeroSize; - NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; - NSImage * closeButton = nil; - - closeButton = [cell isEdited] ? unifiedCloseDirtyButton : unifiedCloseButton; - - if([cell closeButtonOver]) { - closeButton = [cell isEdited] ? unifiedCloseDirtyButtonOver : unifiedCloseButtonOver; - } - if([cell closeButtonPressed]) { - closeButton = [cell isEdited] ? unifiedCloseDirtyButtonDown : unifiedCloseButtonDown; - } - - closeButtonSize = [closeButton size]; - if([controlView isFlipped]) { - closeButtonRect.origin.y += closeButtonRect.size.height; - } - - [closeButton drawAtPoint: closeButtonRect.origin fromRect: CGRectZero operation:NSCompositingOperationSourceOver fraction:1.0]; - - // scoot label over - labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; - } - - // icon - if([cell hasIcon]) { - NSRect iconRect = [self iconRectForTabCell:cell]; - NSImage *icon = [[[cell representedObject] identifier] icon]; - if([controlView isFlipped]) { - iconRect.origin.y += iconRect.size.height; - } - - // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) - if([icon size].width < kPSMTabBarIconWidth) { - iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width) / 2.0; - } - if([icon size].height < kPSMTabBarIconWidth) { - iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height) / 2.0; - } - - [icon drawAtPoint:iconRect.origin fromRect: NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; - - // scoot label over - labelPosition += iconRect.size.width + kPSMTabBarCellPadding; - } - - // label rect - NSRect labelRect; - labelRect.origin.x = labelPosition; - labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; - NSSize s = [[cell attributedStringValue] size]; - labelRect.origin.y = cellFrame.origin.y + (cellFrame.size.height - s.height) / 2.0 - 1.0; - labelRect.size.height = s.height; - - if(![[cell indicator] isHidden]) { - labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); - } - - // object counter - if([cell count] > 0) { - [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; - NSBezierPath *path = [NSBezierPath bezierPath]; - NSRect myRect = [self objectCounterRectForTabCell:cell]; - myRect.origin.y -= 1.0; - [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:270.0 endAngle:90.0]; - [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + myRect.size.height)]; - [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:90.0 endAngle:270.0]; - [path fill]; - - // draw attributed string centered in area - NSRect counterStringRect; - NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; - counterStringRect.size = [counterString size]; - counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; - counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; - [counterString drawInRect:counterStringRect]; - - labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; - } - - // label - [[cell attributedStringValue] drawInRect:labelRect]; +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView *)controlView +{ + NSRect cellFrame = [cell frame]; + CGFloat labelPosition = cellFrame.origin.x + MARGIN_X; + + // close button + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSSize closeButtonSize = NSZeroSize; + NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; + NSImage *closeButton = nil; + + closeButton = [cell isEdited] ? unifiedCloseDirtyButton : unifiedCloseButton; + + if ([cell closeButtonOver]) { + closeButton = [cell isEdited] ? unifiedCloseDirtyButtonOver : unifiedCloseButtonOver; + } + if ([cell closeButtonPressed]) { + closeButton = [cell isEdited] ? unifiedCloseDirtyButtonDown : unifiedCloseButtonDown; + } + + closeButtonSize = [closeButton size]; + if ([controlView isFlipped]) { + closeButtonRect.origin.y += closeButtonRect.size.height; + } + + [closeButton drawAtPoint:closeButtonRect.origin fromRect:CGRectZero operation:NSCompositingOperationSourceOver fraction:1.0]; + + // scoot label over + labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; + } + + // icon + if ([cell hasIcon]) { + NSRect iconRect = [self iconRectForTabCell:cell]; + NSImage *icon = [[[cell representedObject] identifier] icon]; + if ([controlView isFlipped]) { + iconRect.origin.y += iconRect.size.height; + } + + // center in available space (in case icon image is smaller than kPSMTabBarIconWidth) + if ([icon size].width < kPSMTabBarIconWidth) { + iconRect.origin.x += (kPSMTabBarIconWidth - [icon size].width) / 2.0; + } + if ([icon size].height < kPSMTabBarIconWidth) { + iconRect.origin.y -= (kPSMTabBarIconWidth - [icon size].height) / 2.0; + } + + [icon drawAtPoint:iconRect.origin fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1.0]; + + // scoot label over + labelPosition += iconRect.size.width + kPSMTabBarCellPadding; + } + + // label rect + NSRect labelRect; + labelRect.origin.x = labelPosition; + labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; + NSSize s = [[cell attributedStringValue] size]; + labelRect.origin.y = cellFrame.origin.y + (cellFrame.size.height - s.height) / 2.0 - 1.0; + labelRect.size.height = s.height; + + if (![[cell indicator] isHidden]) { + labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); + } + + // object counter + if ([cell count] > 0) { + [[cell countColor] ?: [NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; + NSBezierPath *path = [NSBezierPath bezierPath]; + NSRect myRect = [self objectCounterRectForTabCell:cell]; + myRect.origin.y -= 1.0; + [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; + [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:270.0 endAngle:90.0]; + [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + myRect.size.height)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:90.0 endAngle:270.0]; + [path fill]; + + // draw attributed string centered in area + NSRect counterStringRect; + NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; + counterStringRect.size = [counterString size]; + counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; + counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; + [counterString drawInRect:counterStringRect]; + + labelRect.size.width -= myRect.size.width + kPSMTabBarCellPadding; + } + + // label + [[cell attributedStringValue] drawInRect:labelRect]; } -- (void)drawBackgroundInRect:(NSRect)rect { - //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area - rect = [tabBar bounds]; - - NSRect gradientRect = rect; - gradientRect.size.height -= 1.0; - - NSBezierPath *path = [NSBezierPath bezierPathWithRect:gradientRect]; - [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] - endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; - [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; - [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, NSMaxY(rect) - 0.5) - toPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect) - 0.5)]; - - if(![[[tabBar tabView] window] isKeyWindow]) { - [[NSColor windowBackgroundColor] set]; - NSRectFill(gradientRect); - } +- (void)drawBackgroundInRect:(NSRect)rect +{ + //Draw for our whole bounds; it'll be automatically clipped to fit the appropriate drawing area + rect = [tabBar bounds]; + + NSRect gradientRect = rect; + gradientRect.size.height -= 1.0; + + NSBezierPath *path = [NSBezierPath bezierPathWithRect:gradientRect]; + [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.835 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; + [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x, NSMaxY(rect) - 0.5) + toPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect) - 0.5)]; + + if (![[[tabBar tabView] window] isKeyWindow]) { + [[NSColor windowBackgroundColor] set]; + NSRectFill(gradientRect); + } } -- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect { - tabBar = bar; - [self drawBackgroundInRect:rect]; - - // no tab view == not connected - if(![bar tabView]) { - NSRect labelRect = rect; - labelRect.size.height -= 4.0; - labelRect.origin.y += 4.0; - NSMutableAttributedString *attrStr; - NSString *contents = @"PSMTabBarControl"; - attrStr = [[NSMutableAttributedString alloc] initWithString:contents] ; - NSRange range = NSMakeRange(0, [contents length]); - [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; - NSMutableParagraphStyle *centeredParagraphStyle = nil; - if(!centeredParagraphStyle) { - centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy] ; - [centeredParagraphStyle setAlignment: NSTextAlignmentCenter]; - } - [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; - [attrStr drawInRect:labelRect]; - return; - } - - // draw cells - NSEnumerator *e = [[bar cells] objectEnumerator]; - PSMTabBarCell *cell; - while((cell = [e nextObject])) { - if([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { - [cell drawWithFrame:[cell frame] inView:bar]; - } - } +- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect +{ + tabBar = bar; + [self drawBackgroundInRect:rect]; + + // no tab view == not connected + if (![bar tabView]) { + NSRect labelRect = rect; + labelRect.size.height -= 4.0; + labelRect.origin.y += 4.0; + NSMutableAttributedString *attrStr; + NSString *contents = @"PSMTabBarControl"; + attrStr = [[NSMutableAttributedString alloc] initWithString:contents]; + NSRange range = NSMakeRange(0, [contents length]); + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + NSMutableParagraphStyle *centeredParagraphStyle = nil; + if (!centeredParagraphStyle) { + centeredParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + [centeredParagraphStyle setAlignment:NSTextAlignmentCenter]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; + [attrStr drawInRect:labelRect]; + return; + } + + // draw cells + NSEnumerator *e = [[bar cells] objectEnumerator]; + PSMTabBarCell *cell; + while ((cell = [e nextObject])) { + if ([bar isAnimating] || (![cell isInOverflowMenu] && NSIntersectsRect([cell frame], rect))) { + [cell drawWithFrame:[cell frame] inView:bar]; + } + } } #pragma mark - #pragma mark Archiving -- (void)encodeWithCoder:(NSCoder *)aCoder { - //[super encodeWithCoder:aCoder]; - if([aCoder allowsKeyedCoding]) { - [aCoder encodeObject:unifiedCloseButton forKey:@"unifiedCloseButton"]; - [aCoder encodeObject:unifiedCloseButtonDown forKey:@"unifiedCloseButtonDown"]; - [aCoder encodeObject:unifiedCloseButtonOver forKey:@"unifiedCloseButtonOver"]; - [aCoder encodeObject:unifiedCloseDirtyButton forKey:@"unifiedCloseDirtyButton"]; - [aCoder encodeObject:unifiedCloseDirtyButtonDown forKey:@"unifiedCloseDirtyButtonDown"]; - [aCoder encodeObject:unifiedCloseDirtyButtonOver forKey:@"unifiedCloseDirtyButtonOver"]; - [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; - [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; - [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; - } +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:unifiedCloseButton forKey:@"unifiedCloseButton"]; + [aCoder encodeObject:unifiedCloseButtonDown forKey:@"unifiedCloseButtonDown"]; + [aCoder encodeObject:unifiedCloseButtonOver forKey:@"unifiedCloseButtonOver"]; + [aCoder encodeObject:unifiedCloseDirtyButton forKey:@"unifiedCloseDirtyButton"]; + [aCoder encodeObject:unifiedCloseDirtyButtonDown forKey:@"unifiedCloseDirtyButtonDown"]; + [aCoder encodeObject:unifiedCloseDirtyButtonOver forKey:@"unifiedCloseDirtyButtonOver"]; + [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; + [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; + [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; + } } -- (id)initWithCoder:(NSCoder *)aDecoder { - // self = [super initWithCoder:aDecoder]; - //if (self) { - if([aDecoder allowsKeyedCoding]) { - unifiedCloseButton = [aDecoder decodeObjectForKey:@"unifiedCloseButton"] ; - unifiedCloseButtonDown = [aDecoder decodeObjectForKey:@"unifiedCloseButtonDown"] ; - unifiedCloseButtonOver = [aDecoder decodeObjectForKey:@"unifiedCloseButtonOver"]; - unifiedCloseDirtyButton = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButton"] ; - unifiedCloseDirtyButtonDown = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonDown"] ; - unifiedCloseDirtyButtonOver = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonOver"] ; - _addTabButtonImage = [aDecoder decodeObjectForKey:@"addTabButtonImage"]; - _addTabButtonPressedImage = [aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] ; - _addTabButtonRolloverImage = [aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] ; - } - //} - return self; +- (id)initWithCoder:(NSCoder *)aDecoder +{ + // self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + unifiedCloseButton = [aDecoder decodeObjectForKey:@"unifiedCloseButton"]; + unifiedCloseButtonDown = [aDecoder decodeObjectForKey:@"unifiedCloseButtonDown"]; + unifiedCloseButtonOver = [aDecoder decodeObjectForKey:@"unifiedCloseButtonOver"]; + unifiedCloseDirtyButton = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButton"]; + unifiedCloseDirtyButtonDown = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonDown"]; + unifiedCloseDirtyButtonOver = [aDecoder decodeObjectForKey:@"unifiedCloseDirtyButtonOver"]; + _addTabButtonImage = [aDecoder decodeObjectForKey:@"addTabButtonImage"]; + _addTabButtonPressedImage = [aDecoder decodeObjectForKey:@"addTabButtonPressedImage"]; + _addTabButtonRolloverImage = [aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"]; + } + //} + return self; } @end diff --git a/frontends/cocoa/PreferencesWindowController.m b/frontends/cocoa/PreferencesWindowController.m index 47b71ba8b..d65425355 100644 --- a/frontends/cocoa/PreferencesWindowController.m +++ b/frontends/cocoa/PreferencesWindowController.m @@ -29,28 +29,29 @@ - (instancetype)init { - if ((self = [super initWithWindowNibName: @"PreferencesWindow"]) == nil) return nil; - - return self; + if ((self = [super initWithWindowNibName:@"PreferencesWindow"]) == nil) + return nil; + + return self; } -- (IBAction) useCurrentPageAsHomepage: (id) sender +- (IBAction)useCurrentPageAsHomepage:(id)sender { - struct browser_window *bw = [[(NetSurfApp *)NSApp frontTab] browser]; - const char *url = nsurl_access(browser_window_get_url(bw)); - [self setHomepageURL: [NSString stringWithUTF8String: url]]; + struct browser_window *bw = [[(NetSurfApp *)NSApp frontTab] browser]; + const char *url = nsurl_access(browser_window_get_url(bw)); + [self setHomepageURL:[NSString stringWithUTF8String:url]]; } -- (void) setHomepageURL: (NSString *) newUrl +- (void)setHomepageURL:(NSString *)newUrl { - nsoption_set_charp(homepage_url, strdup( [newUrl UTF8String] )); - [[NSUserDefaults standardUserDefaults] setObject: newUrl forKey: kHomepageURLOption]; - [[NSUserDefaults standardUserDefaults] synchronize]; + nsoption_set_charp(homepage_url, strdup([newUrl UTF8String])); + [[NSUserDefaults standardUserDefaults] setObject:newUrl forKey:kHomepageURLOption]; + [[NSUserDefaults standardUserDefaults] synchronize]; } -- (NSString *) homepageURL +- (NSString *)homepageURL { - return [NSString stringWithUTF8String: nsoption_charp(homepage_url)]; + return [NSString stringWithUTF8String:nsoption_charp(homepage_url)]; } @end diff --git a/frontends/cocoa/ScrollableView.m b/frontends/cocoa/ScrollableView.m index 8f27b2b56..e31d90ade 100644 --- a/frontends/cocoa/ScrollableView.m +++ b/frontends/cocoa/ScrollableView.m @@ -20,52 +20,52 @@ @interface ScrollableView () -- (void) frameChangeNotification: (NSNotification *) note; +- (void)frameChangeNotification:(NSNotification *)note; @end @implementation ScrollableView @synthesize minimumSize; -- (void) setMinimumSize: (NSSize)newSize +- (void)setMinimumSize:(NSSize)newSize { - minimumSize = newSize; - [self adjustFrame]; + minimumSize = newSize; + [self adjustFrame]; } -- (void) adjustFrame +- (void)adjustFrame { - NSSize frameSize = [[self superview] frame].size; - [self setFrameSize: NSMakeSize( MAX( minimumSize.width, frameSize.width ), - MAX( minimumSize.height, frameSize.height ) )]; + NSSize frameSize = [[self superview] frame].size; + [self setFrameSize:NSMakeSize(MAX(minimumSize.width, frameSize.width), + MAX(minimumSize.height, frameSize.height))]; } -- (void) frameChangeNotification: (NSNotification *) note +- (void)frameChangeNotification:(NSNotification *)note { - [self adjustFrame]; + [self adjustFrame]; } -- (void) viewDidMoveToSuperview +- (void)viewDidMoveToSuperview { - if (observedSuperview) { - [[NSNotificationCenter defaultCenter] - removeObserver: self - name: NSViewFrameDidChangeNotification - object: observedSuperview]; - observedSuperview = nil; - } + if (observedSuperview) { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSViewFrameDidChangeNotification + object:observedSuperview]; + observedSuperview = nil; + } - NSView *newSuperView = [self superview]; + NSView *newSuperView = [self superview]; - if (nil != newSuperView) { - observedSuperview = newSuperView; - [[NSNotificationCenter defaultCenter] - addObserver: self - selector: @selector(frameChangeNotification:) - name: NSViewFrameDidChangeNotification - object: observedSuperview]; - [observedSuperview setPostsFrameChangedNotifications: YES]; - } + if (nil != newSuperView) { + observedSuperview = newSuperView; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(frameChangeNotification:) + name:NSViewFrameDidChangeNotification + object:observedSuperview]; + [observedSuperview setPostsFrameChangedNotifications:YES]; + } } @end diff --git a/frontends/cocoa/SearchWindowController.m b/frontends/cocoa/SearchWindowController.m index bbde827bf..5dccc5950 100644 --- a/frontends/cocoa/SearchWindowController.m +++ b/frontends/cocoa/SearchWindowController.m @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #import "cocoa/SearchWindowController.h" #import "cocoa/BrowserViewController.h" @@ -24,12 +23,12 @@ #import "netsurf/browser_window.h" #import "desktop/search.h" -static void cocoa_search_set_back( bool active, void *p ); -static void cocoa_search_set_forward( bool active, void *p ); +static void cocoa_search_set_back(bool active, void *p); +static void cocoa_search_set_forward(bool active, void *p); static struct gui_search_table search_table = { - .forward_state = cocoa_search_set_forward, - .back_state = cocoa_search_set_back, + .forward_state = cocoa_search_set_forward, + .back_state = cocoa_search_set_back, }; struct gui_search_table *cocoa_search_table = &search_table; @@ -45,74 +44,77 @@ struct gui_search_table *cocoa_search_table = &search_table; - (instancetype)init { - if ((self = [super initWithWindowNibName: @"SearchWindow"]) == nil) return nil; - - [self bind: @"browser" toObject: NSApp withKeyPath: @"frontTab" options: nil]; - canGoBack = canGoForward = YES; - - return self; + if ((self = [super initWithWindowNibName:@"SearchWindow"]) == nil) + return nil; + + [self bind:@"browser" toObject:NSApp withKeyPath:@"frontTab" options:nil]; + canGoBack = canGoForward = YES; + + return self; } -- (void) dealloc +- (void)dealloc { - [self unbind: @"browser"]; + [self unbind:@"browser"]; } -- (IBAction) searchNext: (id) sender +- (IBAction)searchNext:(id)sender { - [self search: SearchForward]; + [self search:SearchForward]; } -- (IBAction) searchPrevious: (id) sender +- (IBAction)searchPrevious:(id)sender { - [self search: SearchBackward]; + [self search:SearchBackward]; } -- (void) search: (SearchDirection)direction +- (void)search:(SearchDirection)direction { - search_flags_t flags = (direction == SearchForward) ? SEARCH_FLAG_FORWARDS : 0; - if (caseSensitive) flags |= SEARCH_FLAG_CASE_SENSITIVE; - if (selectAll) flags |= SEARCH_FLAG_SHOWALL; - - struct browser_window *bw = [browser browser]; - browser_window_search( bw, (__bridge void *)self, flags, [searchString UTF8String] ); + search_flags_t flags = (direction == SearchForward) ? SEARCH_FLAG_FORWARDS : 0; + if (caseSensitive) + flags |= SEARCH_FLAG_CASE_SENSITIVE; + if (selectAll) + flags |= SEARCH_FLAG_SHOWALL; + + struct browser_window *bw = [browser browser]; + browser_window_search(bw, (__bridge void *)self, flags, [searchString UTF8String]); } -- (IBAction) searchStringDidChange: (id) sender +- (IBAction)searchStringDidChange:(id)sender { - struct browser_window *bw = [browser browser]; - browser_window_search_clear( bw ); - - [self setCanGoBack: YES]; - [self setCanGoForward: YES]; + struct browser_window *bw = [browser browser]; + browser_window_search_clear(bw); + + [self setCanGoBack:YES]; + [self setCanGoForward:YES]; } -- (void) setCaseSensitive: (BOOL) newValue +- (void)setCaseSensitive:(BOOL)newValue { - if (caseSensitive != newValue) { - caseSensitive = newValue; - [self setCanGoBack: YES]; - [self setCanGoForward: YES]; - } + if (caseSensitive != newValue) { + caseSensitive = newValue; + [self setCanGoBack:YES]; + [self setCanGoForward:YES]; + } } -- (void) setSelectAll: (BOOL) newValue +- (void)setSelectAll:(BOOL)newValue { - if (selectAll != newValue) { - selectAll = newValue; - [self setCanGoBack: YES]; - [self setCanGoForward: YES]; - } + if (selectAll != newValue) { + selectAll = newValue; + [self setCanGoBack:YES]; + [self setCanGoForward:YES]; + } } -static void cocoa_search_set_back( bool active, void *p ) +static void cocoa_search_set_back(bool active, void *p) { - [(__bridge SearchWindowController *)p setCanGoBack: active]; + [(__bridge SearchWindowController *)p setCanGoBack:active]; } -static void cocoa_search_set_forward( bool active, void *p ) +static void cocoa_search_set_forward(bool active, void *p) { - [(__bridge SearchWindowController *)p setCanGoForward: active]; + [(__bridge SearchWindowController *)p setCanGoForward:active]; } @end diff --git a/frontends/cocoa/Tree.m b/frontends/cocoa/Tree.m index c8ab39501..0fa397665 100644 --- a/frontends/cocoa/Tree.m +++ b/frontends/cocoa/Tree.m @@ -29,118 +29,120 @@ @synthesize delegate; -static void tree_redraw_request( int x, int y, int w, int h, void *data ); -static void tree_resized( struct tree *tree, int w, int h, void *data ); -static void tree_scroll_visible( int y, int height, void *data ); -static void tree_get_window_dimensions( int *width, int *height, void *data ); +static void tree_redraw_request(int x, int y, int w, int h, void *data); +static void tree_resized(struct tree *tree, int w, int h, void *data); +static void tree_scroll_visible(int y, int height, void *data); +static void tree_get_window_dimensions(int *width, int *height, void *data); static const struct treeview_table cocoa_tree_callbacks = { - .redraw_request = tree_redraw_request, - .resized = tree_resized, - .scroll_visible = tree_scroll_visible, - .get_window_dimensions = tree_get_window_dimensions + .redraw_request = tree_redraw_request, + .resized = tree_resized, + .scroll_visible = tree_scroll_visible, + .get_window_dimensions = tree_get_window_dimensions }; -- (id)initWithFlags: (unsigned int)flags +- (id)initWithFlags:(unsigned int)flags { - if ((self = [super init]) == nil) return nil; + if ((self = [super init]) == nil) + return nil; - tree = tree_create( flags, &cocoa_tree_callbacks, (__bridge void *)self ); - if (tree == NULL) { - return nil; - } + tree = tree_create(flags, &cocoa_tree_callbacks, (__bridge void *)self); + if (tree == NULL) { + return nil; + } - return self; + return self; } - -- (void) dealloc +- (void)dealloc { - tree_delete( tree ); + tree_delete(tree); } -- (struct tree *) tree +- (struct tree *)tree { - return tree; + return tree; } -- (void) setRedrawing: (BOOL) newRedrawing +- (void)setRedrawing:(BOOL)newRedrawing { } - -+ (void) initialize ++ (void)initialize { } //MARK: - //MARK: Callbacks -static void tree_redraw_request( int x, int y, int w, int h, void *data ) +static void tree_redraw_request(int x, int y, int w, int h, void *data) { - id delegate = ((__bridge Tree *)data)->delegate; - [delegate tree: (__bridge Tree *)data requestedRedrawInRect: cocoa_rect_wh( x, y, w, h )]; + id delegate = ((__bridge Tree *)data)->delegate; + [delegate tree:(__bridge Tree *)data requestedRedrawInRect:cocoa_rect_wh(x, y, w, h)]; } -static void tree_resized( struct tree *tree, int w, int h, void *data ) +static void tree_resized(struct tree *tree, int w, int h, void *data) { - id delegate = ((__bridge Tree *)data)->delegate; - [delegate tree: (__bridge Tree *)data resized: cocoa_size( w, h )]; + id delegate = ((__bridge Tree *)data)->delegate; + [delegate tree:(__bridge Tree *)data resized:cocoa_size(w, h)]; } -static void tree_scroll_visible( int y, int height, void *data ) +static void tree_scroll_visible(int y, int height, void *data) { - id delegate = ((__bridge Tree *)data)->delegate; - [delegate tree: (__bridge Tree *)data scrollPoint: cocoa_point( 0, y )]; + id delegate = ((__bridge Tree *)data)->delegate; + [delegate tree:(__bridge Tree *)data scrollPoint:cocoa_point(0, y)]; } -static void tree_get_window_dimensions( int *width, int *height, void *data ) +static void tree_get_window_dimensions(int *width, int *height, void *data) { - id delegate = ((__bridge Tree *)data)->delegate; - if (delegate == nil) return; + id delegate = ((__bridge Tree *)data)->delegate; + if (delegate == nil) + return; - NSSize size = [delegate treeWindowSize: (__bridge Tree *)data]; + NSSize size = [delegate treeWindowSize:(__bridge Tree *)data]; - if (width != NULL) *width = cocoa_pt_to_px( size.width ); - if (height != NULL) *height = cocoa_pt_to_px( size.height ); + if (width != NULL) + *width = cocoa_pt_to_px(size.width); + if (height != NULL) + *height = cocoa_pt_to_px(size.height); } @end @implementation Tree (ViewInterface) -- (void) drawRect: (NSRect) rect inView: (NSView *) view +- (void)drawRect:(NSRect)rect inView:(NSView *)view { - struct redraw_context ctx = { - .interactive = true, - .background_images = true, - .plot = &cocoa_plotters - }; - - tree_draw(tree, 0, 0, - cocoa_pt_to_px(NSMinX( rect )), - cocoa_pt_to_px(NSMinY( rect )), - cocoa_pt_to_px(NSWidth( rect )), - cocoa_pt_to_px(NSHeight( rect )), - &ctx ); + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &cocoa_plotters + }; + + tree_draw(tree, 0, 0, + cocoa_pt_to_px(NSMinX(rect)), + cocoa_pt_to_px(NSMinY(rect)), + cocoa_pt_to_px(NSWidth(rect)), + cocoa_pt_to_px(NSHeight(rect)), + &ctx); } -- (void) mouseAction: (browser_mouse_state)state atPoint: (NSPoint)point +- (void)mouseAction:(browser_mouse_state)state atPoint:(NSPoint)point { - tree_mouse_action(tree, state, - cocoa_pt_to_px( point.x ), cocoa_pt_to_px( point.y )); + tree_mouse_action(tree, state, + cocoa_pt_to_px(point.x), cocoa_pt_to_px(point.y)); } -- (void) mouseDragEnd: (browser_mouse_state)state fromPoint: (NSPoint)p0 toPoint: (NSPoint) p1 +- (void)mouseDragEnd:(browser_mouse_state)state fromPoint:(NSPoint)p0 toPoint:(NSPoint)p1 { - tree_drag_end(tree, state, - cocoa_pt_to_px( p0.x ), cocoa_pt_to_px( p0.y ), - cocoa_pt_to_px( p1.x ), cocoa_pt_to_px( p1.y )); + tree_drag_end(tree, state, + cocoa_pt_to_px(p0.x), cocoa_pt_to_px(p0.y), + cocoa_pt_to_px(p1.x), cocoa_pt_to_px(p1.y)); } -- (void) keyPress: (uint32_t) key +- (void)keyPress:(uint32_t)key { - tree_keypress( tree, key ); + tree_keypress(tree, key); } @end diff --git a/frontends/cocoa/TreeView.m b/frontends/cocoa/TreeView.m index 6731d9f60..a00e48fd3 100644 --- a/frontends/cocoa/TreeView.m +++ b/frontends/cocoa/TreeView.m @@ -34,217 +34,217 @@ - (void)drawRect:(NSRect)dirtyRect { - [tree drawRect: dirtyRect inView: self]; + [tree drawRect:dirtyRect inView:self]; } -- (BOOL) isFlipped +- (BOOL)isFlipped { - return YES; + return YES; } -- (BOOL) acceptsFirstResponder +- (BOOL)acceptsFirstResponder { - return YES; + return YES; } -- (void) dealloc +- (void)dealloc { - [self setTree: nil]; + [self setTree:nil]; } -- (void) setTree: (Tree *)newTree +- (void)setTree:(Tree *)newTree { - if (tree != newTree) { - [tree setRedrawing: NO]; - [tree setDelegate: nil]; + if (tree != newTree) { + [tree setRedrawing:NO]; + [tree setDelegate:nil]; - tree = newTree ; - [tree setDelegate: self]; - [tree setRedrawing: YES]; + tree = newTree; + [tree setDelegate:self]; + [tree setRedrawing:YES]; - [self setNeedsDisplay: YES]; - } + [self setNeedsDisplay:YES]; + } } //MARK: - //MARK: Event handlers -- (void)mouseDown: (NSEvent *)event +- (void)mouseDown:(NSEvent *)event { - isDragging = NO; - dragStart = [self convertPoint: [event locationInWindow] fromView: nil]; - [tree mouseAction: BROWSER_MOUSE_PRESS_1 atPoint: dragStart]; + isDragging = NO; + dragStart = [self convertPoint:[event locationInWindow] fromView:nil]; + [tree mouseAction:BROWSER_MOUSE_PRESS_1 atPoint:dragStart]; } -#define squared(x) ((x)*(x)) +#define squared(x) ((x) * (x)) #define MinDragDistance (5.0) -- (void) mouseDragged: (NSEvent *)event +- (void)mouseDragged:(NSEvent *)event { - const NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil]; + const NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; - if (!isDragging) { - const CGFloat distance = squared( dragStart.x - point.x ) + squared( dragStart.y - point.y ); - if (distance >= squared( MinDragDistance)) { - isDragging = YES; - } + if (!isDragging) { + const CGFloat distance = squared(dragStart.x - point.x) + squared(dragStart.y - point.y); + if (distance >= squared(MinDragDistance)) { + isDragging = YES; } + } } -- (void) mouseUp: (NSEvent *)event +- (void)mouseUp:(NSEvent *)event { - const NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil]; + const NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; - browser_mouse_state modifierFlags = 0; + browser_mouse_state modifierFlags = 0; - if (isDragging) { - isDragging = NO; - [tree mouseDragEnd: modifierFlags fromPoint: dragStart toPoint: point]; - } else { - modifierFlags |= BROWSER_MOUSE_CLICK_1; - if ([event clickCount] == 2) { - modifierFlags |= BROWSER_MOUSE_DOUBLE_CLICK; - } - [tree mouseAction: modifierFlags atPoint: point]; + if (isDragging) { + isDragging = NO; + [tree mouseDragEnd:modifierFlags fromPoint:dragStart toPoint:point]; + } else { + modifierFlags |= BROWSER_MOUSE_CLICK_1; + if ([event clickCount] == 2) { + modifierFlags |= BROWSER_MOUSE_DOUBLE_CLICK; } + [tree mouseAction:modifierFlags atPoint:point]; + } } //MARK: Keyboard events -- (void) keyDown: (NSEvent *)theEvent +- (void)keyDown:(NSEvent *)theEvent { - [self interpretKeyEvents: [NSArray arrayWithObject: theEvent]]; + [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; } -- (void) insertText: (id)string +- (void)insertText:(id)string { - for (NSUInteger i = 0, length = [string length]; i < length; i++) { - unichar ch = [string characterAtIndex: i]; - [tree keyPress: ch]; - } + for (NSUInteger i = 0, length = [string length]; i < length; i++) { + unichar ch = [string characterAtIndex:i]; + [tree keyPress:ch]; + } } -- (void) moveLeft: (id)sender +- (void)moveLeft:(id)sender { - [tree keyPress: NS_KEY_LEFT]; + [tree keyPress:NS_KEY_LEFT]; } -- (void) moveRight: (id)sender +- (void)moveRight:(id)sender { - [tree keyPress: NS_KEY_RIGHT]; + [tree keyPress:NS_KEY_RIGHT]; } -- (void) moveUp: (id)sender +- (void)moveUp:(id)sender { - [tree keyPress: NS_KEY_UP]; + [tree keyPress:NS_KEY_UP]; } -- (void) moveDown: (id)sender +- (void)moveDown:(id)sender { - [tree keyPress: NS_KEY_DOWN]; + [tree keyPress:NS_KEY_DOWN]; } -- (void) deleteBackward: (id)sender +- (void)deleteBackward:(id)sender { - [tree keyPress: NS_KEY_DELETE_LEFT]; + [tree keyPress:NS_KEY_DELETE_LEFT]; } -- (void) deleteForward: (id)sender +- (void)deleteForward:(id)sender { - [tree keyPress: NS_KEY_DELETE_RIGHT]; + [tree keyPress:NS_KEY_DELETE_RIGHT]; } -- (void) cancelOperation: (id)sender +- (void)cancelOperation:(id)sender { - [tree keyPress: NS_KEY_ESCAPE]; + [tree keyPress:NS_KEY_ESCAPE]; } -- (void) scrollPageUp: (id)sender +- (void)scrollPageUp:(id)sender { - [tree keyPress: NS_KEY_PAGE_UP]; + [tree keyPress:NS_KEY_PAGE_UP]; } -- (void) scrollPageDown: (id)sender +- (void)scrollPageDown:(id)sender { - [tree keyPress: NS_KEY_PAGE_DOWN]; + [tree keyPress:NS_KEY_PAGE_DOWN]; } -- (void) insertTab: (id)sender +- (void)insertTab:(id)sender { - [tree keyPress: NS_KEY_TAB]; + [tree keyPress:NS_KEY_TAB]; } -- (void) insertBacktab: (id)sender +- (void)insertBacktab:(id)sender { - [tree keyPress: NS_KEY_SHIFT_TAB]; + [tree keyPress:NS_KEY_SHIFT_TAB]; } -- (void) moveToBeginningOfLine: (id)sender +- (void)moveToBeginningOfLine:(id)sender { - [tree keyPress: NS_KEY_LINE_START]; + [tree keyPress:NS_KEY_LINE_START]; } -- (void) moveToEndOfLine: (id)sender +- (void)moveToEndOfLine:(id)sender { - [tree keyPress: NS_KEY_LINE_END]; + [tree keyPress:NS_KEY_LINE_END]; } -- (void) moveToBeginningOfDocument: (id)sender +- (void)moveToBeginningOfDocument:(id)sender { - [tree keyPress: NS_KEY_TEXT_START]; + [tree keyPress:NS_KEY_TEXT_START]; } -- (void) moveToEndOfDocument: (id)sender +- (void)moveToEndOfDocument:(id)sender { - [tree keyPress: NS_KEY_TEXT_END]; + [tree keyPress:NS_KEY_TEXT_END]; } -- (void) insertNewline: (id)sender +- (void)insertNewline:(id)sender { - [tree keyPress: NS_KEY_NL]; + [tree keyPress:NS_KEY_NL]; } -- (void) selectAll: (id)sender +- (void)selectAll:(id)sender { - [tree keyPress: NS_KEY_SELECT_ALL]; + [tree keyPress:NS_KEY_SELECT_ALL]; } -- (void) copy: (id) sender +- (void)copy:(id)sender { - [tree keyPress: NS_KEY_COPY_SELECTION]; + [tree keyPress:NS_KEY_COPY_SELECTION]; } -- (void) cut: (id) sender +- (void)cut:(id)sender { - [tree keyPress: NS_KEY_CUT_SELECTION]; + [tree keyPress:NS_KEY_CUT_SELECTION]; } -- (void) paste: (id) sender +- (void)paste:(id)sender { - [tree keyPress: NS_KEY_PASTE]; + [tree keyPress:NS_KEY_PASTE]; } //MARK: - //MARK: Tree delegate methods -- (void) tree: (Tree *)t requestedRedrawInRect: (NSRect) rect +- (void)tree:(Tree *)t requestedRedrawInRect:(NSRect)rect { - [self setNeedsDisplayInRect: rect]; + [self setNeedsDisplayInRect:rect]; } -- (void) tree: (Tree *)t resized: (NSSize) size +- (void)tree:(Tree *)t resized:(NSSize)size { - [self setMinimumSize: size]; + [self setMinimumSize:size]; } -- (void) tree: (Tree *)t scrollPoint: (NSPoint) point +- (void)tree:(Tree *)t scrollPoint:(NSPoint)point { - [self scrollPoint: point]; + [self scrollPoint:point]; } -- (NSSize) treeWindowSize: (Tree *)t +- (NSSize)treeWindowSize:(Tree *)t { - return [self frame].size; + return [self frame].size; } @end diff --git a/frontends/cocoa/URLFieldCell.m b/frontends/cocoa/URLFieldCell.m index e08ba3efc..6c36f17c4 100644 --- a/frontends/cocoa/URLFieldCell.m +++ b/frontends/cocoa/URLFieldCell.m @@ -25,176 +25,197 @@ @property (readonly, retain, nonatomic) NSButtonCell *refreshCell; -- (NSRect) buttonFrame: (NSRect) cellFrame; -- (NSRect) urlFrame: (NSRect) cellFrame; -- (NSRect) iconFrame: (NSRect) cellFrame; +- (NSRect)buttonFrame:(NSRect)cellFrame; +- (NSRect)urlFrame:(NSRect)cellFrame; +- (NSRect)iconFrame:(NSRect)cellFrame; @end - @implementation URLFieldCell @synthesize favicon; -- (void) setFavicon: (NSImage *)newIcon +- (void)setFavicon:(NSImage *)newIcon { - if (favicon != newIcon) { - favicon = newIcon ; - [[self controlView] setNeedsDisplay: YES]; - } + if (favicon != newIcon) { + favicon = newIcon; + [[self controlView] setNeedsDisplay:YES]; + } } #define BUTTON_SIZE 32 #define PADDING 2 -- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView *)controlView +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - [favicon drawInRect: [self iconFrame: cellFrame] fromRect: NSZeroRect - operation: NSCompositingOperationSourceOver fraction: 1.0]; + [favicon drawInRect:[self iconFrame:cellFrame] + fromRect:NSZeroRect + operation:NSCompositingOperationSourceOver + fraction:1.0]; - [super drawInteriorWithFrame: [self urlFrame: cellFrame] inView: controlView]; + [super drawInteriorWithFrame:[self urlFrame:cellFrame] inView:controlView]; - [[self refreshCell] drawInteriorWithFrame: [self buttonFrame: cellFrame] - inView: controlView]; + [[self refreshCell] drawInteriorWithFrame:[self buttonFrame:cellFrame] + inView:controlView]; } -- (void) selectWithFrame: (NSRect)aRect inView: (NSView *)controlView editor: (NSText *)textObj - delegate: (id)anObject start: (NSInteger)selStart length: (NSInteger)selLength +- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj + delegate:(id)anObject + start:(NSInteger)selStart + length:(NSInteger)selLength { - const NSRect textFrame = [self urlFrame: aRect]; - [super selectWithFrame: textFrame inView: controlView editor: textObj - delegate: anObject start: selStart length: selLength]; + const NSRect textFrame = [self urlFrame:aRect]; + [super selectWithFrame:textFrame + inView:controlView + editor:textObj + delegate:anObject + start:selStart + length:selLength]; } -- (void) editWithFrame: (NSRect)aRect inView: (NSView *)controlView editor: (NSText *)textObj - delegate: (id)anObject event: (NSEvent *)theEvent +- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj + delegate:(id)anObject + event:(NSEvent *)theEvent { - const NSRect textFrame = [self urlFrame: aRect]; - [super editWithFrame: textFrame inView: controlView editor: textObj - delegate: anObject event: theEvent]; + const NSRect textFrame = [self urlFrame:aRect]; + [super editWithFrame:textFrame + inView:controlView + editor:textObj + delegate:anObject + event:theEvent]; } -- (void) startDragURLAt: (NSPoint) point inView: (NSView *) view +- (void)startDragURLAt:(NSPoint)point inView:(NSView *)view { - NSString *url = [self stringValue]; - NSString *title = url; - nsurl *nsurl; - - if (nsurl_create( [url UTF8String] , &nsurl ) != NSERROR_OK) - return; - - const struct url_data *data = urldb_get_url_data( nsurl ); - - nsurl_unref(nsurl); - - if (data && data->title) title = [NSString stringWithUTF8String: data->title]; - - NSPasteboard *pb = [NSPasteboard pasteboardWithName: NSDragPboard]; - [pb declareTypes: [NSArray arrayWithObjects: NSStringPboardType, NSURLPboardType, - @"public.url", @"public.url-name", nil] owner: nil]; - [pb setString: url forType: NSStringPboardType]; - [pb setString: url forType: @"public.url"]; - [pb setString: title forType: @"public.url-name"]; - [[NSURL URLWithString: url] writeToPasteboard: pb]; - - NSRect urlBounds = NSZeroRect; - urlBounds.size = [title sizeWithAttributes: nil]; - urlBounds.size.width += urlBounds.size.height + 2; - - NSImage *image = [[NSImage alloc] initWithSize: urlBounds.size]; - - [image lockFocus]; - [favicon drawInRect: NSMakeRect( urlBounds.origin.x, urlBounds.origin.y, urlBounds.size.height, urlBounds.size.height ) - fromRect: NSZeroRect operation: NSCompositingOperationCopy fraction: 1.0]; - urlBounds.origin.x += urlBounds.size.height + 2; - [title drawInRect: urlBounds withAttributes: nil]; - [image unlockFocus]; - - point.x -= urlBounds.size.height / 2; - point.y += urlBounds.size.height / 2; - - [view dragImage: image at: point offset: NSZeroSize event: [NSApp currentEvent] - pasteboard: pb source: self slideBack: YES]; + NSString *url = [self stringValue]; + NSString *title = url; + nsurl *nsurl; + + if (nsurl_create([url UTF8String], &nsurl) != NSERROR_OK) + return; + + const struct url_data *data = urldb_get_url_data(nsurl); + + nsurl_unref(nsurl); + + if (data && data->title) + title = [NSString stringWithUTF8String:data->title]; + + NSPasteboard *pb = [NSPasteboard pasteboardWithName:NSDragPboard]; + [pb declareTypes:[NSArray arrayWithObjects:NSStringPboardType, NSURLPboardType, + @"public.url", @"public.url-name", nil] + owner:nil]; + [pb setString:url forType:NSStringPboardType]; + [pb setString:url forType:@"public.url"]; + [pb setString:title forType:@"public.url-name"]; + [[NSURL URLWithString:url] writeToPasteboard:pb]; + + NSRect urlBounds = NSZeroRect; + urlBounds.size = [title sizeWithAttributes:nil]; + urlBounds.size.width += urlBounds.size.height + 2; + + NSImage *image = [[NSImage alloc] initWithSize:urlBounds.size]; + + [image lockFocus]; + [favicon drawInRect:NSMakeRect(urlBounds.origin.x, urlBounds.origin.y, urlBounds.size.height, urlBounds.size.height) + fromRect:NSZeroRect + operation:NSCompositingOperationCopy + fraction:1.0]; + urlBounds.origin.x += urlBounds.size.height + 2; + [title drawInRect:urlBounds withAttributes:nil]; + [image unlockFocus]; + + point.x -= urlBounds.size.height / 2; + point.y += urlBounds.size.height / 2; + + [view dragImage:image + at:point + offset:NSZeroSize + event:[NSApp currentEvent] + pasteboard:pb + source:self + slideBack:YES]; } - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { - return NSDragOperationCopy | NSDragOperationGeneric; + return NSDragOperationCopy | NSDragOperationGeneric; } -- (BOOL) trackMouse: (NSEvent *)theEvent inRect: (NSRect)cellFrame ofView: (NSView *)controlView untilMouseUp: (BOOL)flag +- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag { - const NSPoint point = [controlView convertPoint: [theEvent locationInWindow] fromView: nil]; - const NSRect buttonRect = [self buttonFrame: cellFrame]; - if (NSPointInRect( point, [self iconFrame: cellFrame] )) { - [self startDragURLAt: point inView: controlView]; - return NO; - } else if (NSPointInRect( point, buttonRect )) { - return [[self refreshCell] trackMouse: theEvent inRect: buttonRect - ofView: controlView untilMouseUp: flag]; - } else { - cellFrame.size.width -= BUTTON_SIZE + PADDING; - return [super trackMouse: theEvent inRect: cellFrame ofView: controlView untilMouseUp: YES]; - } + const NSPoint point = [controlView convertPoint:[theEvent locationInWindow] fromView:nil]; + const NSRect buttonRect = [self buttonFrame:cellFrame]; + if (NSPointInRect(point, [self iconFrame:cellFrame])) { + [self startDragURLAt:point inView:controlView]; + return NO; + } else if (NSPointInRect(point, buttonRect)) { + return [[self refreshCell] trackMouse:theEvent + inRect:buttonRect + ofView:controlView + untilMouseUp:flag]; + } else { + cellFrame.size.width -= BUTTON_SIZE + PADDING; + return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:YES]; + } } - -- (NSRect) buttonFrame: (NSRect) cellFrame +- (NSRect)buttonFrame:(NSRect)cellFrame { - NSRect buttonRect = cellFrame; - buttonRect.origin.x = NSMaxX( cellFrame ) - BUTTON_SIZE; - buttonRect.size.width = BUTTON_SIZE; - return buttonRect; + NSRect buttonRect = cellFrame; + buttonRect.origin.x = NSMaxX(cellFrame) - BUTTON_SIZE; + buttonRect.size.width = BUTTON_SIZE; + return buttonRect; } -- (NSRect) urlFrame: (NSRect) cellFrame +- (NSRect)urlFrame:(NSRect)cellFrame { - NSRect textFrame = cellFrame; - textFrame.origin.x += cellFrame.size.height; - textFrame.size.width -= cellFrame.size.height + BUTTON_SIZE + PADDING; - return textFrame; + NSRect textFrame = cellFrame; + textFrame.origin.x += cellFrame.size.height; + textFrame.size.width -= cellFrame.size.height + BUTTON_SIZE + PADDING; + return textFrame; } -- (NSRect) iconFrame: (NSRect)cellFrame +- (NSRect)iconFrame:(NSRect)cellFrame { - NSRect iconFrame = { - .origin = { - .x = cellFrame.origin.x + PADDING, - .y = cellFrame.origin.y, - }, - .size = NSMakeSize( NSHeight( cellFrame ), NSHeight( cellFrame ) ) - }; - return NSInsetRect( iconFrame, 2 * PADDING, 2 * PADDING ); + NSRect iconFrame = { + .origin = { + .x = cellFrame.origin.x + PADDING, + .y = cellFrame.origin.y, + }, + .size = NSMakeSize(NSHeight(cellFrame), NSHeight(cellFrame)) + }; + return NSInsetRect(iconFrame, 2 * PADDING, 2 * PADDING); } -- (NSButtonCell *) refreshCell +- (NSButtonCell *)refreshCell { - if (nil == refreshCell) { - refreshCell = [[NSButtonCell alloc] initImageCell: [NSImage imageNamed: NSImageNameRefreshTemplate]]; - [refreshCell setButtonType: NSMomentaryPushInButton]; - [refreshCell setBordered: NO]; - } - return refreshCell; + if (nil == refreshCell) { + refreshCell = [[NSButtonCell alloc] initImageCell:[NSImage imageNamed:NSImageNameRefreshTemplate]]; + [refreshCell setButtonType:NSMomentaryPushInButton]; + [refreshCell setBordered:NO]; + } + return refreshCell; } -- (void) setRefreshTarget: (id) newTarget +- (void)setRefreshTarget:(id)newTarget { - [[self refreshCell] setTarget: newTarget]; + [[self refreshCell] setTarget:newTarget]; } -- (id) refreshTarget +- (id)refreshTarget { - return [[self refreshCell] target]; + return [[self refreshCell] target]; } -- (void) setRefreshAction: (SEL) newAction +- (void)setRefreshAction:(SEL)newAction { - [[self refreshCell] setAction: newAction]; + [[self refreshCell] setAction:newAction]; } -- (SEL) refreshAction +- (SEL)refreshAction { - return [[self refreshCell] action]; + return [[self refreshCell] action]; } @end diff --git a/frontends/cocoa/apple_image.m b/frontends/cocoa/apple_image.m index a14cd10e5..89a760969 100644 --- a/frontends/cocoa/apple_image.m +++ b/frontends/cocoa/apple_image.m @@ -32,66 +32,65 @@ #import "cocoa/bitmap.h" typedef struct apple_image_content { - struct content base; + struct content base; - struct bitmap *bitmap; /**< Created NetSurf bitmap */ + struct bitmap *bitmap; /**< Created NetSurf bitmap */ - NSUInteger frames; - NSUInteger currentFrame; - int *frameTimes; + NSUInteger frames; + NSUInteger currentFrame; + int *frameTimes; } apple_image_content; - static void *apple_image_get_internal(const struct content *c, void *context) { - apple_image_content *ai_c = (apple_image_content *)c; - return ai_c->bitmap; + apple_image_content *ai_c = (apple_image_content *)c; + return ai_c->bitmap; } static nserror apple_image_create(const content_handler *handler, - lwc_string *imime_type, const struct http_parameter *params, - llcache_handle *llcache, const char *fallback_charset, - bool quirks, struct content **c) + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c) { - apple_image_content *ai; - nserror error; + apple_image_content *ai; + nserror error; - ai = calloc(1, sizeof(apple_image_content)); - if (ai == NULL) - return NSERROR_NOMEM; + ai = calloc(1, sizeof(apple_image_content)); + if (ai == NULL) + return NSERROR_NOMEM; - error = content__init(&ai->base, handler, imime_type, params, - llcache, fallback_charset, quirks); - if (error != NSERROR_OK) { - free(ai); - return error; - } + error = content__init(&ai->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + free(ai); + return error; + } - *c = (struct content *) ai; + *c = (struct content *)ai; - return NSERROR_OK; + return NSERROR_OK; } - -static void animate_image_cb( void *ptr ) +static void animate_image_cb(void *ptr) { - struct apple_image_content *ai = ptr; - ++ai->currentFrame; - if (ai->currentFrame >= ai->frames) ai->currentFrame = 0; - - [(__bridge NSBitmapImageRep *)ai->bitmap setProperty: NSImageCurrentFrame withValue: [NSNumber numberWithUnsignedInteger: ai->currentFrame]]; - cocoa_bitmap_modified( ai->bitmap ); - - union content_msg_data data; - data.redraw.full_redraw = true; - data.redraw.x = data.redraw.object_x = 0; - data.redraw.y = data.redraw.object_y = 0; - data.redraw.width = data.redraw.object_width = ai->base.width; - data.redraw.height = data.redraw.object_height = ai->base.height; - data.redraw.object = &ai->base; - content_broadcast( &ai->base, CONTENT_MSG_REDRAW, data ); - - cocoa_schedule(ai->frameTimes[ai->currentFrame], animate_image_cb, ai ); + struct apple_image_content *ai = ptr; + ++ai->currentFrame; + if (ai->currentFrame >= ai->frames) + ai->currentFrame = 0; + + [(__bridge NSBitmapImageRep *)ai->bitmap setProperty:NSImageCurrentFrame withValue:[NSNumber numberWithUnsignedInteger:ai->currentFrame]]; + cocoa_bitmap_modified(ai->bitmap); + + union content_msg_data data; + data.redraw.full_redraw = true; + data.redraw.x = data.redraw.object_x = 0; + data.redraw.y = data.redraw.object_y = 0; + data.redraw.width = data.redraw.object_width = ai->base.width; + data.redraw.height = data.redraw.object_height = ai->base.height; + data.redraw.object = &ai->base; + content_broadcast(&ai->base, CONTENT_MSG_REDRAW, data); + + cocoa_schedule(ai->frameTimes[ai->currentFrame], animate_image_cb, ai); } /** @@ -99,160 +98,160 @@ static void animate_image_cb( void *ptr ) */ static bool apple_image_convert(struct content *c) { - apple_image_content *ai_c = (apple_image_content *)c; - unsigned long size; - const char *bytes = content__get_source_data(c, &size); - - NSData *data = [NSData dataWithBytesNoCopy: (char *)bytes length: size freeWhenDone: NO]; - NSBitmapImageRep *image = [NSBitmapImageRep imageRepWithData: data]; - - if (image == nil) { - union content_msg_data msg_data; - msg_data.error = "cannot decode image"; - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - return false; - } - - c->width = [image pixelsWide]; - c->height = [image pixelsHigh]; - ai_c->bitmap = (__bridge_retained void *)image; - - NSString *url = [NSString stringWithUTF8String: nsurl_access(llcache_handle_get_url( content_get_llcache_handle( c )) )]; - NSString *title = [NSString stringWithFormat: @"%@ (%dx%d)", [url lastPathComponent], c->width, c->height]; - content__set_title(c, [title UTF8String] ); - - content_set_ready(c); - content_set_done(c); - content_set_status(c, ""); - - struct apple_image_content *ai = (struct apple_image_content *)c; - NSUInteger frames = [[image valueForProperty: NSImageFrameCount] unsignedIntegerValue]; - if (frames > 1) { - ai->frames = frames; - ai->currentFrame = 0; - ai->frameTimes = calloc( ai->frames , sizeof(int)); - for (NSUInteger i = 0; i < frames; i++) { - [image setProperty: NSImageCurrentFrame withValue: [NSNumber numberWithUnsignedInteger: i]]; - ai->frameTimes[i] = 1000 * [[image valueForProperty: NSImageCurrentFrameDuration] floatValue]; - } - [image setProperty: NSImageCurrentFrame withValue: [NSNumber numberWithUnsignedInteger: 0]]; - cocoa_schedule( ai->frameTimes[0], animate_image_cb, ai ); - } - - return true; + apple_image_content *ai_c = (apple_image_content *)c; + unsigned long size; + const char *bytes = content__get_source_data(c, &size); + + NSData *data = [NSData dataWithBytesNoCopy:(char *)bytes length:size freeWhenDone:NO]; + NSBitmapImageRep *image = [NSBitmapImageRep imageRepWithData:data]; + + if (image == nil) { + union content_msg_data msg_data; + msg_data.error = "cannot decode image"; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + c->width = [image pixelsWide]; + c->height = [image pixelsHigh]; + ai_c->bitmap = (__bridge_retained void *)image; + + NSString *url = [NSString stringWithUTF8String:nsurl_access(llcache_handle_get_url(content_get_llcache_handle(c)))]; + NSString *title = [NSString stringWithFormat:@"%@ (%dx%d)", [url lastPathComponent], c->width, c->height]; + content__set_title(c, [title UTF8String]); + + content_set_ready(c); + content_set_done(c); + content_set_status(c, ""); + + struct apple_image_content *ai = (struct apple_image_content *)c; + NSUInteger frames = [[image valueForProperty:NSImageFrameCount] unsignedIntegerValue]; + if (frames > 1) { + ai->frames = frames; + ai->currentFrame = 0; + ai->frameTimes = calloc(ai->frames, sizeof(int)); + for (NSUInteger i = 0; i < frames; i++) { + [image setProperty:NSImageCurrentFrame withValue:[NSNumber numberWithUnsignedInteger:i]]; + ai->frameTimes[i] = 1000 * [[image valueForProperty:NSImageCurrentFrameDuration] floatValue]; + } + [image setProperty:NSImageCurrentFrame withValue:[NSNumber numberWithUnsignedInteger:0]]; + cocoa_schedule(ai->frameTimes[0], animate_image_cb, ai); + } + + return true; } - static void apple_image_destroy(struct content *c) { - apple_image_content *ai_c = (apple_image_content *)c; + apple_image_content *ai_c = (apple_image_content *)c; - id bitmap = (__bridge_transfer id)ai_c->bitmap; + id bitmap = (__bridge_transfer id)ai_c->bitmap; bitmap = nil; - - ai_c->bitmap = NULL; - cocoa_schedule(-1, animate_image_cb, c ); -} + ai_c->bitmap = NULL; + cocoa_schedule(-1, animate_image_cb, c); +} static nserror apple_image_clone(const struct content *old, struct content **newc) { - apple_image_content *ai; - apple_image_content *ai_old = (apple_image_content *)old; - nserror error; - - ai = calloc(1, sizeof(apple_image_content)); - if (ai == NULL) - return NSERROR_NOMEM; - - error = content__clone(old, &ai->base); - if (error != NSERROR_OK) { - content_destroy(&ai->base); - return error; - } - - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { - ai->base.width = old->width; - ai->base.height = old->height; - ai->bitmap = (__bridge_retained void *)((__bridge id)ai_old->bitmap); - } - - *newc = (struct content *) ai; - - return NSERROR_OK; + apple_image_content *ai; + apple_image_content *ai_old = (apple_image_content *)old; + nserror error; + + ai = calloc(1, sizeof(apple_image_content)); + if (ai == NULL) + return NSERROR_NOMEM; + + error = content__clone(old, &ai->base); + if (error != NSERROR_OK) { + content_destroy(&ai->base); + return error; + } + + if (old->status == CONTENT_STATUS_READY || old->status == CONTENT_STATUS_DONE) { + ai->base.width = old->width; + ai->base.height = old->height; + ai->bitmap = (__bridge_retained void *)((__bridge id)ai_old->bitmap); + } + + *newc = (struct content *)ai; + + return NSERROR_OK; } static content_type apple_image_content_type(void) { - return CONTENT_IMAGE; + return CONTENT_IMAGE; } /** * Redraw a CONTENT_APPLE_IMAGE with appropriate tiling. */ static bool apple_image_redraw(struct content *c, struct content_redraw_data *data, - const struct rect *clip, const struct redraw_context *ctx) + const struct rect *clip, const struct redraw_context *ctx) { - apple_image_content *ai_c = (apple_image_content *)c; - bitmap_flags_t flags = BITMAPF_NONE; + apple_image_content *ai_c = (apple_image_content *)c; + bitmap_flags_t flags = BITMAPF_NONE; - if (data->repeat_x) - flags |= BITMAPF_REPEAT_X; - if (data->repeat_y) - flags |= BITMAPF_REPEAT_Y; + if (data->repeat_x) + flags |= BITMAPF_REPEAT_X; + if (data->repeat_y) + flags |= BITMAPF_REPEAT_Y; - return ctx->plot->bitmap(ctx, ai_c->bitmap, data->x, data->y, data->width, data->height, - data->background_colour, flags); + return ctx->plot->bitmap(ctx, ai_c->bitmap, data->x, data->y, data->width, data->height, + data->background_colour, flags); } static const content_handler apple_image_content_handler = { - .create = apple_image_create, - .data_complete = apple_image_convert, - .destroy = apple_image_destroy, - .redraw = apple_image_redraw, - .clone = apple_image_clone, - .get_internal = apple_image_get_internal, - .type = apple_image_content_type, - .no_share = false + .create = apple_image_create, + .data_complete = apple_image_convert, + .destroy = apple_image_destroy, + .redraw = apple_image_redraw, + .clone = apple_image_clone, + .get_internal = apple_image_get_internal, + .type = apple_image_content_type, + .no_share = false }; -static nserror register_for_type( NSString *mime ) +static nserror register_for_type(NSString *mime) { - const char *type = [mime UTF8String]; - /* nsgif has priority since it supports animated GIF */ + const char *type = [mime UTF8String]; +/* nsgif has priority since it supports animated GIF */ #ifdef WITH_GIF - if (strcmp(type, "image/gif") == 0) - return NSERROR_OK; + if (strcmp(type, "image/gif") == 0) + return NSERROR_OK; #endif - nserror error = content_factory_register_handler( type, &apple_image_content_handler ); - if (error != NSERROR_OK) return error; + nserror error = content_factory_register_handler(type, &apple_image_content_handler); + if (error != NSERROR_OK) + return error; - return NSERROR_OK; + return NSERROR_OK; } /* exported interface documented in cocoa/apple_image.h */ nserror apple_image_init(void) { - NSArray *utis = [NSBitmapImageRep imageTypes]; - for (NSString *uti in utis) { - NSDictionary *declaration = (__bridge_transfer NSDictionary *)UTTypeCopyDeclaration( (__bridge CFStringRef)uti ); - id mimeTypes = [[declaration objectForKey: (NSString *)kUTTypeTagSpecificationKey] objectForKey: (NSString *)kUTTagClassMIMEType]; - - if (mimeTypes == nil) continue; - - if (![mimeTypes isKindOfClass: [NSArray class]]) { - mimeTypes = [NSArray arrayWithObject: mimeTypes]; - } - - for (NSString *mime in mimeTypes) { - nserror error = register_for_type( mime ); - if (error != NSERROR_OK) return error; - } - } - - return NSERROR_OK; + NSArray *utis = [NSBitmapImageRep imageTypes]; + for (NSString *uti in utis) { + NSDictionary *declaration = (__bridge_transfer NSDictionary *)UTTypeCopyDeclaration((__bridge CFStringRef)uti); + id mimeTypes = [[declaration objectForKey:(NSString *)kUTTypeTagSpecificationKey] objectForKey:(NSString *)kUTTagClassMIMEType]; + + if (mimeTypes == nil) + continue; + + if (![mimeTypes isKindOfClass:[NSArray class]]) { + mimeTypes = [NSArray arrayWithObject:mimeTypes]; + } + + for (NSString *mime in mimeTypes) { + nserror error = register_for_type(mime); + if (error != NSERROR_OK) + return error; + } + } + + return NSERROR_OK; } #endif /* WITH_APPLE_IMAGE */ diff --git a/frontends/cocoa/bitmap.m b/frontends/cocoa/bitmap.m index 30127e360..597a5af79 100644 --- a/frontends/cocoa/bitmap.m +++ b/frontends/cocoa/bitmap.m @@ -40,243 +40,244 @@ #define BLUE_OFFSET (2) #define ALPHA_OFFSET (3) -static CGImageRef cocoa_prepare_bitmap( void *bitmap ); +static CGImageRef cocoa_prepare_bitmap(void *bitmap); //static NSMapTable *cocoa_get_bitmap_cache( void ); -static inline NSMapTable *cocoa_get_bitmap_cache( void ) +static inline NSMapTable *cocoa_get_bitmap_cache(void) { - static NSMapTable *cache = nil; - if (cache == nil) { - cache = NSCreateMapTable( NSNonOwnedPointerMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0 ); - } - return cache; + static NSMapTable *cache = nil; + if (cache == nil) { + cache = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0); + } + return cache; } static int bitmap_get_width(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return (int)[bmp pixelsWide]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return (int)[bmp pixelsWide]; } static int bitmap_get_height(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return (int)[bmp pixelsHigh]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return (int)[bmp pixelsHigh]; } static bool bitmap_get_opaque(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return [bmp isOpaque]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return [bmp isOpaque]; } static void bitmap_destroy(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); + NSCParameterAssert(NULL != bitmap); - NSMapTable *cache = cocoa_get_bitmap_cache(); - CGImageRef image = NSMapGet( cache, bitmap ); - if (NULL != image) { - CGImageRelease( image ); - NSMapRemove( cache, bitmap ); - } + NSMapTable *cache = cocoa_get_bitmap_cache(); + CGImageRef image = NSMapGet(cache, bitmap); + if (NULL != image) { + CGImageRelease(image); + NSMapRemove(cache, bitmap); + } - NSBitmapImageRep *bmp = (__bridge_transfer NSBitmapImageRep *)bitmap; + NSBitmapImageRep *bmp = (__bridge_transfer NSBitmapImageRep *)bitmap; bmp = nil; } static void *bitmap_create(int width, int height, unsigned int state) { - NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] - initWithBitmapDataPlanes: NULL - pixelsWide: width - pixelsHigh: height - bitsPerSample: BITS_PER_SAMPLE - samplesPerPixel: SAMPLES_PER_PIXEL - hasAlpha: YES - isPlanar: NO - colorSpaceName: NSDeviceRGBColorSpace - bitmapFormat: NSAlphaNonpremultipliedBitmapFormat - bytesPerRow: BYTES_PER_PIXEL * width - bitsPerPixel: BITS_PER_PIXEL]; - - return (__bridge_retained void *)bmp; + NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:width + pixelsHigh:height + bitsPerSample:BITS_PER_SAMPLE + samplesPerPixel:SAMPLES_PER_PIXEL + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:NSAlphaNonpremultipliedBitmapFormat + bytesPerRow:BYTES_PER_PIXEL * width + bitsPerPixel:BITS_PER_PIXEL]; + + return (__bridge_retained void *)bmp; } static void bitmap_set_opaque(void *bitmap, bool opaque) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - [bmp setOpaque: opaque ? YES : NO]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + [bmp setOpaque:opaque ? YES : NO]; } static unsigned char *bitmap_get_buffer(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return [bmp bitmapData]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return [bmp bitmapData]; } static size_t bitmap_get_rowstride(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return [bmp bytesPerRow]; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return [bmp bytesPerRow]; } static size_t bitmap_get_bpp(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - return [bmp bitsPerPixel] / 8; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + return [bmp bitsPerPixel] / 8; } static bool bitmap_test_opaque(void *bitmap) { - NSCParameterAssert( bitmap_get_bpp( bitmap ) == BYTES_PER_PIXEL ); + NSCParameterAssert(bitmap_get_bpp(bitmap) == BYTES_PER_PIXEL); - unsigned char *buf = bitmap_get_buffer( bitmap ); + unsigned char *buf = bitmap_get_buffer(bitmap); - const size_t height = bitmap_get_height( bitmap ); - const size_t width = bitmap_get_width( bitmap ); + const size_t height = bitmap_get_height(bitmap); + const size_t width = bitmap_get_width(bitmap); - const size_t line_step = bitmap_get_rowstride( bitmap ) - BYTES_PER_PIXEL * width; + const size_t line_step = bitmap_get_rowstride(bitmap) - BYTES_PER_PIXEL * width; - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < height; x++) { - if (buf[ALPHA_OFFSET] != 0xFF) return false; - buf += BYTES_PER_PIXEL; - } - buf += line_step; - } + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < height; x++) { + if (buf[ALPHA_OFFSET] != 0xFF) + return false; + buf += BYTES_PER_PIXEL; + } + buf += line_step; + } - return true; + return true; } static bool bitmap_save(void *bitmap, const char *path, unsigned flags) { - NSCParameterAssert( NULL != bitmap ); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + NSCParameterAssert(NULL != bitmap); + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - NSData *tiff = [bmp TIFFRepresentation]; - return [tiff writeToFile: [NSString stringWithUTF8String: path] atomically: YES]; + NSData *tiff = [bmp TIFFRepresentation]; + return [tiff writeToFile:[NSString stringWithUTF8String:path] atomically:YES]; } void cocoa_bitmap_modified(void *bitmap) { - NSMapTable *cache = cocoa_get_bitmap_cache(); - CGImageRef image = NSMapGet( cache, bitmap ); - if (NULL != image) { - CGImageRelease( image ); - NSMapRemove( cache, bitmap ); - } + NSMapTable *cache = cocoa_get_bitmap_cache(); + CGImageRef image = NSMapGet(cache, bitmap); + if (NULL != image) { + CGImageRelease(image); + NSMapRemove(cache, bitmap); + } } -CGImageRef cocoa_get_cgimage( void *bitmap ) +CGImageRef cocoa_get_cgimage(void *bitmap) { - NSMapTable *cache = cocoa_get_bitmap_cache(); + NSMapTable *cache = cocoa_get_bitmap_cache(); - CGImageRef result = NSMapGet( cache, bitmap ); - if (NULL == result) { - result = cocoa_prepare_bitmap( bitmap ); - NSMapInsertKnownAbsent( cache, bitmap, result ); - } + CGImageRef result = NSMapGet(cache, bitmap); + if (NULL == result) { + result = cocoa_prepare_bitmap(bitmap); + NSMapInsertKnownAbsent(cache, bitmap, result); + } - return result; + return result; } - -static CGImageRef cocoa_prepare_bitmap( void *bitmap ) +static CGImageRef cocoa_prepare_bitmap(void *bitmap) { - NSCParameterAssert( NULL != bitmap ); + NSCParameterAssert(NULL != bitmap); - NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; + NSBitmapImageRep *bmp = (__bridge NSBitmapImageRep *)bitmap; - size_t w = [bmp pixelsWide]; - size_t h = [bmp pixelsHigh]; + size_t w = [bmp pixelsWide]; + size_t h = [bmp pixelsHigh]; - CGImageRef original = [bmp CGImage]; + CGImageRef original = [bmp CGImage]; - if (h <= 1) return CGImageRetain( original ); + if (h <= 1) + return CGImageRetain(original); - void *data = malloc( 4 * w * h ); + void *data = malloc(4 * w * h); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE, - BYTES_PER_PIXEL * w, colorSpace, - [bmp isOpaque] ? kCGImageAlphaNoneSkipLast - : kCGImageAlphaPremultipliedLast ); - CGColorSpaceRelease( colorSpace ); + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(data, w, h, BITS_PER_SAMPLE, + BYTES_PER_PIXEL * w, colorSpace, + [bmp isOpaque] ? kCGImageAlphaNoneSkipLast + : kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(colorSpace); - CGContextTranslateCTM( context, 0.0, h ); - CGContextScaleCTM( context, 1.0, -1.0 ); + CGContextTranslateCTM(context, 0.0, h); + CGContextScaleCTM(context, 1.0, -1.0); - CGRect rect = CGRectMake( 0, 0, w, h ); - CGContextClearRect( context, rect ); - CGContextDrawImage( context, rect, original ); + CGRect rect = CGRectMake(0, 0, w, h); + CGContextClearRect(context, rect); + CGContextDrawImage(context, rect, original); - CGImageRef result = CGBitmapContextCreateImage( context ); + CGImageRef result = CGBitmapContextCreateImage(context); - CGContextRelease( context ); - free( data ); + CGContextRelease(context); + free(data); - return result; + return result; } static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) { - int bwidth = bitmap_get_width( bitmap ); - int bheight = bitmap_get_height( bitmap ); + int bwidth = bitmap_get_width(bitmap); + int bheight = bitmap_get_height(bitmap); - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &cocoa_plotters - }; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &cocoa_plotters + }; - CGColorSpaceRef cspace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ); - CGContextRef bitmapContext = CGBitmapContextCreate( bitmap_get_buffer( bitmap ), - bwidth, bheight, - bitmap_get_bpp( bitmap ) * 8 / 4, - bitmap_get_rowstride( bitmap ), - cspace, kCGImageAlphaNoneSkipLast ); - CGColorSpaceRelease( cspace ); + CGColorSpaceRef cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + CGContextRef bitmapContext = CGBitmapContextCreate(bitmap_get_buffer(bitmap), + bwidth, bheight, + bitmap_get_bpp(bitmap) * 8 / 4, + bitmap_get_rowstride(bitmap), + cspace, kCGImageAlphaNoneSkipLast); + CGColorSpaceRelease(cspace); - int width = MIN( content_get_width( content ), 1024 ); - int height = ((width * bheight) + bwidth / 2) / bwidth; + int width = MIN(content_get_width(content), 1024); + int height = ((width * bheight) + bwidth / 2) / bwidth; - CGContextTranslateCTM( bitmapContext, 0, bheight ); - CGContextScaleCTM( bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height ); + CGContextTranslateCTM(bitmapContext, 0, bheight); + CGContextScaleCTM(bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height); - [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: bitmapContext flipped: YES]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:bitmapContext flipped:YES]]; - content_scaled_redraw( content, width, height, &ctx ); + content_scaled_redraw(content, width, height, &ctx); - [NSGraphicsContext setCurrentContext: nil]; - CGContextRelease( bitmapContext ); + [NSGraphicsContext setCurrentContext:nil]; + CGContextRelease(bitmapContext); - cocoa_bitmap_modified( bitmap ); + cocoa_bitmap_modified(bitmap); - return true; + return true; } static struct gui_bitmap_table bitmap_table = { - .create = bitmap_create, - .destroy = bitmap_destroy, - .set_opaque = bitmap_set_opaque, - .get_opaque = bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, - .get_buffer = bitmap_get_buffer, - .get_rowstride = bitmap_get_rowstride, - .get_width = bitmap_get_width, - .get_height = bitmap_get_height, - .get_bpp = bitmap_get_bpp, - .save = bitmap_save, - .modified = cocoa_bitmap_modified, - .render = bitmap_render, + .create = bitmap_create, + .destroy = bitmap_destroy, + .set_opaque = bitmap_set_opaque, + .get_opaque = bitmap_get_opaque, + .test_opaque = bitmap_test_opaque, + .get_buffer = bitmap_get_buffer, + .get_rowstride = bitmap_get_rowstride, + .get_width = bitmap_get_width, + .get_height = bitmap_get_height, + .get_bpp = bitmap_get_bpp, + .save = bitmap_save, + .modified = cocoa_bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *cocoa_bitmap_table = &bitmap_table; diff --git a/frontends/cocoa/desktop-tree.m b/frontends/cocoa/desktop-tree.m index 30af768a7..1015f9358 100644 --- a/frontends/cocoa/desktop-tree.m +++ b/frontends/cocoa/desktop-tree.m @@ -39,10 +39,10 @@ #import "cocoa/desktop-tree.h" struct tree { - unsigned int flags; /* Tree flags */ - tree_drag_type drag; - const struct treeview_table *callbacks; - void *client_data; /* User assigned data for the callbacks */ + unsigned int flags; /* Tree flags */ + tree_drag_type drag; + const struct treeview_table *callbacks; + void *client_data; /* User assigned data for the callbacks */ }; #include "netsurf/misc.h" @@ -57,299 +57,295 @@ struct sslcert_session_data *ssl_current_session = NULL; const char *tree_hotlist_path = NULL; static nserror treeview_test_redraw_request(struct core_window *cw, - const struct rect *r) + const struct rect *r) { - struct tree *tree = (struct tree *)cw; + struct tree *tree = (struct tree *)cw; - tree->callbacks->redraw_request(r->x0, r->y0, - r->x1 - r->x0, r->y1 - r->y0, - tree->client_data); + tree->callbacks->redraw_request(r->x0, r->y0, + r->x1 - r->x0, r->y1 - r->y0, + tree->client_data); return NSERROR_OK; } static void treeview_test_update_size(struct core_window *cw, - int width, int height) + int width, int height) { - struct tree *tree = (struct tree *)cw; + struct tree *tree = (struct tree *)cw; - tree->callbacks->resized(tree, width, height, tree->client_data); + tree->callbacks->resized(tree, width, height, tree->client_data); } static void treeview_test_scroll_visible(struct core_window *cw, - const struct rect *r) + const struct rect *r) { } static void treeview_test_get_window_dimensions(struct core_window *cw, - int *width, int *height) + int *width, int *height) { - struct tree *tree = (struct tree *)cw; + struct tree *tree = (struct tree *)cw; - tree->callbacks->get_window_dimensions(width, height, - tree->client_data); + tree->callbacks->get_window_dimensions(width, height, + tree->client_data); } static void treeview_test_drag_status(struct core_window *cw, - core_window_drag_status ds) + core_window_drag_status ds) { - struct tree *tree = (struct tree *)cw; + struct tree *tree = (struct tree *)cw; - switch (ds) { - case CORE_WINDOW_DRAG_NONE: - tree->drag = TREE_NO_DRAG; - break; + switch (ds) { + case CORE_WINDOW_DRAG_NONE: + tree->drag = TREE_NO_DRAG; + break; - case CORE_WINDOW_DRAG_SELECTION: - tree->drag = TREE_SELECT_DRAG; - break; + case CORE_WINDOW_DRAG_SELECTION: + tree->drag = TREE_SELECT_DRAG; + break; - case CORE_WINDOW_DRAG_MOVE: - tree->drag = TREE_MOVE_DRAG; - break; + case CORE_WINDOW_DRAG_MOVE: + tree->drag = TREE_MOVE_DRAG; + break; - case CORE_WINDOW_DRAG_TEXT_SELECTION: - tree->drag = TREE_TEXTAREA_DRAG; - break; + case CORE_WINDOW_DRAG_TEXT_SELECTION: + tree->drag = TREE_TEXTAREA_DRAG; + break; - default: - break; - } + default: + break; + } } struct core_window_callback_table cw_t = { - .invalidate = treeview_test_redraw_request, - .update_size = treeview_test_update_size, - .scroll_visible = treeview_test_scroll_visible, - .get_window_dimensions = treeview_test_get_window_dimensions, - .drag_status = treeview_test_drag_status + .invalidate = treeview_test_redraw_request, + .update_size = treeview_test_update_size, + .scroll_visible = treeview_test_scroll_visible, + .get_window_dimensions = treeview_test_get_window_dimensions, + .drag_status = treeview_test_drag_status }; static bool treeview_test_init(struct tree *tree) { - nserror err; - - switch (tree->flags) { - case TREE_COOKIES: - err = cookie_manager_init(&cw_t, (struct core_window *)tree); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't init new cookie manager.", 0); - break; - case TREE_HISTORY: - err = global_history_init(&cw_t, (struct core_window *)tree); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't init new global history.", 0); - break; - case TREE_HOTLIST: - err = hotlist_init(tree_hotlist_path, tree_hotlist_path); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't init new hotlist.", 0); - err = hotlist_manager_init(&cw_t, (struct core_window *)tree); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't init hotlist manager.", 0); - break; - case TREE_SSLCERT: - assert(ssl_current_session == NULL && - "Call sslcert_viewer_init directly, " - "this compat. layer can't cope with simultanious " - "sslcert viewers"); - err = sslcert_viewer_init(&cw_t, (struct core_window *)tree, - ssl_current_session); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't init new sslcert viewer.", 0); - break; - } - - return true; + nserror err; + + switch (tree->flags) { + case TREE_COOKIES: + err = cookie_manager_init(&cw_t, (struct core_window *)tree); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't init new cookie manager.", 0); + break; + case TREE_HISTORY: + err = global_history_init(&cw_t, (struct core_window *)tree); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't init new global history.", 0); + break; + case TREE_HOTLIST: + err = hotlist_init(tree_hotlist_path, tree_hotlist_path); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't init new hotlist.", 0); + err = hotlist_manager_init(&cw_t, (struct core_window *)tree); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't init hotlist manager.", 0); + break; + case TREE_SSLCERT: + assert(ssl_current_session == NULL && "Call sslcert_viewer_init directly, " + "this compat. layer can't cope with simultanious " + "sslcert viewers"); + err = sslcert_viewer_init(&cw_t, (struct core_window *)tree, + ssl_current_session); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't init new sslcert viewer.", 0); + break; + } + + return true; } static bool treeview_test_fini(struct tree *tree) { - nserror err; - - switch (tree->flags) { - case TREE_COOKIES: - err = cookie_manager_fini(); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't finalise cookie manager.", 0); - break; - case TREE_HISTORY: - err = global_history_fini(); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't finalise cookie manager.", 0); - break; - case TREE_HOTLIST: - err = hotlist_fini(); - if (err != NSERROR_OK) - guit->misc->warning("Couldn't finalise hotlist.", 0); - break; - case TREE_SSLCERT: - assert(ssl_current_session != NULL && - "Can't use sslcert window after sslcert_viewer_fini()"); - err = sslcert_viewer_fini(ssl_current_session); - ssl_current_session = NULL; - if (err != NSERROR_OK) - guit->misc->warning("Couldn't finalise sslcert viewer.", 0); - break; - } - - return true; + nserror err; + + switch (tree->flags) { + case TREE_COOKIES: + err = cookie_manager_fini(); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't finalise cookie manager.", 0); + break; + case TREE_HISTORY: + err = global_history_fini(); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't finalise cookie manager.", 0); + break; + case TREE_HOTLIST: + err = hotlist_fini(); + if (err != NSERROR_OK) + guit->misc->warning("Couldn't finalise hotlist.", 0); + break; + case TREE_SSLCERT: + assert(ssl_current_session != NULL && "Can't use sslcert window after sslcert_viewer_fini()"); + err = sslcert_viewer_fini(ssl_current_session); + ssl_current_session = NULL; + if (err != NSERROR_OK) + guit->misc->warning("Couldn't finalise sslcert viewer.", 0); + break; + } + + return true; } static bool treeview_test_redraw(struct tree *tree, int x, int y, - int clip_x, int clip_y, int clip_width, int clip_height, - const struct redraw_context *ctx) + int clip_x, int clip_y, int clip_width, int clip_height, + const struct redraw_context *ctx) { - struct rect clip; - - clip.x0 = clip_x; - clip.y0 = clip_y; - clip.x1 = clip_x + clip_width; - clip.y1 = clip_y + clip_height; - - switch (tree->flags) { - case TREE_SSLCERT: - if (ssl_current_session != NULL) { - sslcert_viewer_redraw(ssl_current_session, x, y, &clip, ctx); - } - return true; - case TREE_COOKIES: - cookie_manager_redraw(x, y, &clip, ctx); - return true; - case TREE_HISTORY: - global_history_redraw(x, y, &clip, ctx); - return true; - case TREE_HOTLIST: - hotlist_redraw(x, y, &clip, ctx); - return true; - } - - return false; + struct rect clip; + + clip.x0 = clip_x; + clip.y0 = clip_y; + clip.x1 = clip_x + clip_width; + clip.y1 = clip_y + clip_height; + + switch (tree->flags) { + case TREE_SSLCERT: + if (ssl_current_session != NULL) { + sslcert_viewer_redraw(ssl_current_session, x, y, &clip, ctx); + } + return true; + case TREE_COOKIES: + cookie_manager_redraw(x, y, &clip, ctx); + return true; + case TREE_HISTORY: + global_history_redraw(x, y, &clip, ctx); + return true; + case TREE_HOTLIST: + hotlist_redraw(x, y, &clip, ctx); + return true; + } + + return false; } static bool treeview_test_mouse_action(struct tree *tree, - browser_mouse_state mouse, int x, int y) + browser_mouse_state mouse, int x, int y) { - switch (tree->flags) { - case TREE_SSLCERT: - assert(ssl_current_session != NULL && - "Can't use sslcert window after sslcert_viewer_fini()"); - sslcert_viewer_mouse_action(ssl_current_session, mouse, x, y); - return true; - case TREE_COOKIES: - cookie_manager_mouse_action(mouse, x, y); - return true; - case TREE_HISTORY: - global_history_mouse_action(mouse, x, y); - return true; - case TREE_HOTLIST: - hotlist_mouse_action(mouse, x, y); - return true; - } - - return false; + switch (tree->flags) { + case TREE_SSLCERT: + assert(ssl_current_session != NULL && "Can't use sslcert window after sslcert_viewer_fini()"); + sslcert_viewer_mouse_action(ssl_current_session, mouse, x, y); + return true; + case TREE_COOKIES: + cookie_manager_mouse_action(mouse, x, y); + return true; + case TREE_HISTORY: + global_history_mouse_action(mouse, x, y); + return true; + case TREE_HOTLIST: + hotlist_mouse_action(mouse, x, y); + return true; + } + + return false; } static bool treeview_test_keypress(struct tree *tree, uint32_t key) { - switch (tree->flags) { - case TREE_SSLCERT: - assert(ssl_current_session != NULL && - "Can't use sslcert window after sslcert_viewer_fini()"); - sslcert_viewer_keypress(ssl_current_session, key); - return true; - case TREE_COOKIES: - cookie_manager_keypress(key); - return true; - case TREE_HISTORY: - global_history_keypress(key); - return true; - case TREE_HOTLIST: - hotlist_keypress(key); - return true; - } - - return false; + switch (tree->flags) { + case TREE_SSLCERT: + assert(ssl_current_session != NULL && "Can't use sslcert window after sslcert_viewer_fini()"); + sslcert_viewer_keypress(ssl_current_session, key); + return true; + case TREE_COOKIES: + cookie_manager_keypress(key); + return true; + case TREE_HISTORY: + global_history_keypress(key); + return true; + case TREE_HOTLIST: + hotlist_keypress(key); + return true; + } + + return false; } /* -------------------------------------------------------------------------- */ /** deprecated compatibility layer for new treeview modules. Do not use. */ struct tree *tree_create(unsigned int flags, - const struct treeview_table *callbacks, void *client_data) + const struct treeview_table *callbacks, void *client_data) { - struct tree *tree; + struct tree *tree; - tree = calloc(sizeof(struct tree), 1); - if (tree == NULL) { - LOG("calloc failed"); - guit->misc->warning(messages_get_errorcode(NSERROR_NOMEM), 0); - return NULL; - } + tree = calloc(sizeof(struct tree), 1); + if (tree == NULL) { + LOG("calloc failed"); + guit->misc->warning(messages_get_errorcode(NSERROR_NOMEM), 0); + return NULL; + } - tree->flags = flags; - tree->drag = TREE_NO_DRAG; - tree->callbacks = callbacks; - tree->client_data = client_data; + tree->flags = flags; + tree->drag = TREE_NO_DRAG; + tree->callbacks = callbacks; + tree->client_data = client_data; - treeview_test_init(tree); + treeview_test_init(tree); - return tree; + return tree; } /** deprecated compatibility layer for new treeview modules. Do not use. */ void tree_delete(struct tree *tree) { - treeview_test_fini(tree); - free(tree); + treeview_test_fini(tree); + free(tree); } /** deprecated compatibility layer for new treeview modules. Do not use. */ void tree_draw(struct tree *tree, int x, int y, - int clip_x, int clip_y, int clip_width, int clip_height, - const struct redraw_context *ctx) + int clip_x, int clip_y, int clip_width, int clip_height, + const struct redraw_context *ctx) { - assert(tree != NULL); + assert(tree != NULL); - treeview_test_redraw(tree, x, y, clip_x, clip_y, - clip_width, clip_height, ctx); + treeview_test_redraw(tree, x, y, clip_x, clip_y, + clip_width, clip_height, ctx); } /** deprecated compatibility layer for new treeview modules. Do not use. */ bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse, int x, - int y) + int y) { - assert(tree != NULL); + assert(tree != NULL); - if (treeview_test_mouse_action(tree, mouse, x, y)) { - return true; - } + if (treeview_test_mouse_action(tree, mouse, x, y)) { + return true; + } - return false; + return false; } /** deprecated compatibility layer for new treeview modules. Do not use. */ void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0, - int x1, int y1) + int x1, int y1) { - assert(tree != NULL); + assert(tree != NULL); - treeview_test_mouse_action(tree, BROWSER_MOUSE_HOVER, x1, y1); + treeview_test_mouse_action(tree, BROWSER_MOUSE_HOVER, x1, y1); } /** deprecated compatibility layer for new treeview modules. Do not use. */ bool tree_keypress(struct tree *tree, uint32_t key) { - if (treeview_test_keypress(tree, key)) { - return true; - } + if (treeview_test_keypress(tree, key)) { + return true; + } - return false; + return false; } /** deprecated compatibility layer for new treeview modules. Do not use. */ tree_drag_type tree_drag_status(struct tree *tree) { - assert(tree != NULL); - return tree->drag; + assert(tree != NULL); + return tree->drag; } diff --git a/frontends/cocoa/fetch.m b/frontends/cocoa/fetch.m index 8760d68e3..74ba9afa3 100644 --- a/frontends/cocoa/fetch.m +++ b/frontends/cocoa/fetch.m @@ -27,86 +27,86 @@ static char cocoafiletype[200]; static const struct mimemap_s { - const char * const extension; - const char * const mimetype; + const char *const extension; + const char *const mimetype; } cocoamimemap[] = { - { "css", "text/css" }, - { "f79", "text/css" }, - { "jpg", "image/jpeg" }, - { "jpeg", "image/jpeg" }, - { "gif", "image/gif" }, - { "png", "image/png" }, - { "b60", "image/png" }, - { "jng", "image/jng" }, - { "svg", "image/svg" }, - { NULL, "text/html" } + { "css", "text/css" }, + { "f79", "text/css" }, + { "jpg", "image/jpeg" }, + { "jpeg", "image/jpeg" }, + { "gif", "image/gif" }, + { "png", "image/png" }, + { "b60", "image/png" }, + { "jng", "image/jng" }, + { "svg", "image/svg" }, + { NULL, "text/html" } }; - static const char *fetch_filetype(const char *unix_path) { - NSString *uti; - NSString *mimeType = nil; - NSError *utiError = nil; + NSString *uti; + NSString *mimeType = nil; + NSError *utiError = nil; - uti = [[NSWorkspace sharedWorkspace] typeOfFile: [NSString stringWithUTF8String: unix_path] error:&utiError]; - if (nil != uti) { - LOG("Looking for mimetype from uti \"%s\"", [uti UTF8String] ); - mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass( (__bridge CFStringRef)uti, kUTTagClassMIMEType ); - } else { - NSAlert *utiAlert = [NSAlert alertWithError:utiError]; - [utiAlert runModal]; // Ignore return value. + uti = [[NSWorkspace sharedWorkspace] typeOfFile:[NSString stringWithUTF8String:unix_path] error:&utiError]; + if (nil != uti) { + LOG("Looking for mimetype from uti \"%s\"", [uti UTF8String]); + mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassMIMEType); + } else { + NSAlert *utiAlert = [NSAlert alertWithError:utiError]; + [utiAlert runModal]; // Ignore return value. - LOG("uti call failed"); + LOG("uti call failed"); - strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); - return cocoafiletype; - } + strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); + return cocoafiletype; + } - if (nil != mimeType) { - strncpy(cocoafiletype, [mimeType UTF8String], sizeof(cocoafiletype)); - } else { - const char *extension; + if (nil != mimeType) { + strncpy(cocoafiletype, [mimeType UTF8String], sizeof(cocoafiletype)); + } else { + const char *extension; - LOG("mimetype from uti failed"); + LOG("mimetype from uti failed"); - extension = [(__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass( (__bridge CFStringRef)uti, kUTTagClassFilenameExtension) UTF8String]; + extension = [(__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassFilenameExtension) UTF8String]; - if (extension == NULL) { - /* give up and go with default */ - LOG("No extension going with default type"); - strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); } else { - int eidx = 0; /* index of extension entry */ + if (extension == NULL) { + /* give up and go with default */ + LOG("No extension going with default type"); + strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); + } else { + int eidx = 0; /* index of extension entry */ - while ((cocoamimemap[eidx].extension != NULL) && - (strcmp(cocoamimemap[eidx].extension, extension) != 0)) { - eidx++; - } + while ((cocoamimemap[eidx].extension != NULL) && (strcmp(cocoamimemap[eidx].extension, extension) != 0)) { + eidx++; + } - strncpy(cocoafiletype, - cocoamimemap[eidx].mimetype, - sizeof(cocoafiletype)); - } - } + strncpy(cocoafiletype, + cocoamimemap[eidx].mimetype, + sizeof(cocoafiletype)); + } + } - LOG("\tMIME type for '%s' is '%s'", unix_path, cocoafiletype); + LOG("\tMIME type for '%s' is '%s'", unix_path, cocoafiletype); - return cocoafiletype; + return cocoafiletype; } static nsurl *gui_get_resource_url(const char *path) { - nsurl *url = NULL; - NSString *nspath = [[NSBundle mainBundle] pathForResource: [NSString stringWithUTF8String: path] ofType: @""]; - if (nspath == nil) return NULL; - nsurl_create([[[NSURL fileURLWithPath: nspath] absoluteString] UTF8String], &url); - return url; + nsurl *url = NULL; + NSString *nspath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:path] ofType:@""]; + if (nspath == nil) + return NULL; + nsurl_create([[[NSURL fileURLWithPath:nspath] absoluteString] UTF8String], &url); + return url; } static struct gui_fetch_table fetch_table = { - .filetype = fetch_filetype, + .filetype = fetch_filetype, - .get_resource_url = gui_get_resource_url, + .get_resource_url = gui_get_resource_url, }; struct gui_fetch_table *cocoa_fetch_table = &fetch_table; diff --git a/frontends/cocoa/font.m b/frontends/cocoa/font.m index 66ee5d090..daed97fae 100644 --- a/frontends/cocoa/font.m +++ b/frontends/cocoa/font.m @@ -26,215 +26,226 @@ #import "cocoa/plotter.h" #import "cocoa/font.h" -static NSLayoutManager *cocoa_prepare_layout_manager( const char *string, size_t length, - const plot_font_style_t *style ); +static NSLayoutManager *cocoa_prepare_layout_manager(const char *string, size_t length, + const plot_font_style_t *style); -static CGFloat cocoa_layout_width( NSLayoutManager *layout ); -static CGFloat cocoa_layout_width_chars( NSLayoutManager *layout, size_t characters ); -static NSUInteger cocoa_glyph_for_location( NSLayoutManager *layout, CGFloat x ); -static size_t cocoa_bytes_for_characters( const char *string, size_t characters ); -static NSDictionary *cocoa_font_attributes( const plot_font_style_t *style ); +static CGFloat cocoa_layout_width(NSLayoutManager *layout); +static CGFloat cocoa_layout_width_chars(NSLayoutManager *layout, size_t characters); +static NSUInteger cocoa_glyph_for_location(NSLayoutManager *layout, CGFloat x); +static size_t cocoa_bytes_for_characters(const char *string, size_t characters); +static NSDictionary *cocoa_font_attributes(const plot_font_style_t *style); static NSTextStorage *cocoa_text_storage = nil; static NSTextContainer *cocoa_text_container = nil; static nserror cocoa_font_width(const plot_font_style_t *style, - const char *string, size_t length, - int *width) + const char *string, size_t length, + int *width) { - NSLayoutManager *layout; - layout = cocoa_prepare_layout_manager( string, length, style ); - *width = cocoa_layout_width( layout ); - return NSERROR_OK; + NSLayoutManager *layout; + layout = cocoa_prepare_layout_manager(string, length, style); + *width = cocoa_layout_width(layout); + return NSERROR_OK; } static nserror cocoa_font_position(const plot_font_style_t *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) { - NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style ); - if (layout == nil) { - return NSERROR_BAD_PARAMETER; - } - - NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x ); - NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex]; - - if (chars >= [cocoa_text_storage length]) *char_offset = length; - else *char_offset = cocoa_bytes_for_characters( string, chars ); - - *actual_x = cocoa_pt_to_px( NSMaxX( [layout boundingRectForGlyphRange: NSMakeRange( glyphIndex - 1, 1 ) - inTextContainer: cocoa_text_container] ) ); - - return NSERROR_OK; + NSLayoutManager *layout = cocoa_prepare_layout_manager(string, length, style); + if (layout == nil) { + return NSERROR_BAD_PARAMETER; + } + + NSUInteger glyphIndex = cocoa_glyph_for_location(layout, x); + NSUInteger chars = [layout characterIndexForGlyphAtIndex:glyphIndex]; + + if (chars >= [cocoa_text_storage length]) + *char_offset = length; + else + *char_offset = cocoa_bytes_for_characters(string, chars); + + *actual_x = cocoa_pt_to_px(NSMaxX([layout boundingRectForGlyphRange:NSMakeRange(glyphIndex - 1, 1) + inTextContainer:cocoa_text_container])); + + return NSERROR_OK; } static nserror cocoa_font_split(const plot_font_style_t *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) { - NSLayoutManager *layout = cocoa_prepare_layout_manager( string, length, style ); - if (layout == nil) return NSERROR_BAD_PARAMETER; - - NSUInteger glyphIndex = cocoa_glyph_for_location( layout, x ); - NSUInteger chars = [layout characterIndexForGlyphAtIndex: glyphIndex]; - - if (chars >= [cocoa_text_storage length]) { - *char_offset = length; - *actual_x = cocoa_layout_width( layout ); - return NSERROR_OK; - } - - - chars = [[cocoa_text_storage string] rangeOfString: @" " options: NSBackwardsSearch range: NSMakeRange( 0, chars + 1 )].location; - if (chars == NSNotFound) { - *char_offset = 0; - *actual_x = 0; - return NSERROR_OK; - } - - *char_offset = cocoa_bytes_for_characters( string, chars ); - *actual_x = cocoa_layout_width_chars( layout, chars ); - - return NSERROR_OK; + NSLayoutManager *layout = cocoa_prepare_layout_manager(string, length, style); + if (layout == nil) + return NSERROR_BAD_PARAMETER; + + NSUInteger glyphIndex = cocoa_glyph_for_location(layout, x); + NSUInteger chars = [layout characterIndexForGlyphAtIndex:glyphIndex]; + + if (chars >= [cocoa_text_storage length]) { + *char_offset = length; + *actual_x = cocoa_layout_width(layout); + return NSERROR_OK; + } + + chars = [[cocoa_text_storage string] rangeOfString:@" " options:NSBackwardsSearch range:NSMakeRange(0, chars + 1)].location; + if (chars == NSNotFound) { + *char_offset = 0; + *actual_x = 0; + return NSERROR_OK; + } + + *char_offset = cocoa_bytes_for_characters(string, chars); + *actual_x = cocoa_layout_width_chars(layout, chars); + + return NSERROR_OK; } - static struct gui_layout_table layout_table = { - .width = cocoa_font_width, - .position = cocoa_font_position, - .split = cocoa_font_split, + .width = cocoa_font_width, + .position = cocoa_font_position, + .split = cocoa_font_split, }; struct gui_layout_table *cocoa_layout_table = &layout_table; - #pragma mark - -void cocoa_draw_string( CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style ) +void cocoa_draw_string(CGFloat x, CGFloat y, const char *bytes, size_t length, const plot_font_style_t *style) { - NSLayoutManager *layout = cocoa_prepare_layout_manager( bytes, length, style ); - if (layout == nil) return; - - NSFont *font = [cocoa_text_storage attribute: NSFontAttributeName atIndex: 0 effectiveRange: NULL]; - CGFloat baseline = [layout defaultLineHeightForFont: font] * 3.0 / 4.0; - - NSRange glyphRange = [layout glyphRangeForTextContainer: cocoa_text_container]; - [layout drawGlyphsForGlyphRange: glyphRange atPoint: NSMakePoint( x, y - baseline )]; -} + NSLayoutManager *layout = cocoa_prepare_layout_manager(bytes, length, style); + if (layout == nil) + return; + + NSFont *font = [cocoa_text_storage attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL]; + CGFloat baseline = [layout defaultLineHeightForFont:font] * 3.0 / 4.0; + NSRange glyphRange = [layout glyphRangeForTextContainer:cocoa_text_container]; + [layout drawGlyphsForGlyphRange:glyphRange atPoint:NSMakePoint(x, y - baseline)]; +} #pragma mark - -static inline CGFloat cocoa_layout_width( NSLayoutManager *layout ) +static inline CGFloat cocoa_layout_width(NSLayoutManager *layout) { - if (layout == nil) return 0.0; - - return cocoa_pt_to_px( NSWidth( [layout usedRectForTextContainer: cocoa_text_container] ) ); + if (layout == nil) + return 0.0; + + return cocoa_pt_to_px(NSWidth([layout usedRectForTextContainer:cocoa_text_container])); } -static inline CGFloat cocoa_layout_width_chars( NSLayoutManager *layout, size_t characters ) +static inline CGFloat cocoa_layout_width_chars(NSLayoutManager *layout, size_t characters) { - NSUInteger glyphIndex = [layout glyphIndexForCharacterAtIndex: characters]; - return cocoa_pt_to_px( [layout locationForGlyphAtIndex: glyphIndex].x ); + NSUInteger glyphIndex = [layout glyphIndexForCharacterAtIndex:characters]; + return cocoa_pt_to_px([layout locationForGlyphAtIndex:glyphIndex].x); } -static inline NSUInteger cocoa_glyph_for_location( NSLayoutManager *layout, CGFloat x ) +static inline NSUInteger cocoa_glyph_for_location(NSLayoutManager *layout, CGFloat x) { - CGFloat fraction = 0.0; - NSUInteger glyphIndex = [layout glyphIndexForPoint: NSMakePoint( cocoa_px_to_pt( x ), 0 ) - inTextContainer: cocoa_text_container - fractionOfDistanceThroughGlyph: &fraction]; - if (fraction >= 1.0) ++glyphIndex; - return glyphIndex; + CGFloat fraction = 0.0; + NSUInteger glyphIndex = [layout glyphIndexForPoint:NSMakePoint(cocoa_px_to_pt(x), 0) + inTextContainer:cocoa_text_container + fractionOfDistanceThroughGlyph:&fraction]; + if (fraction >= 1.0) + ++glyphIndex; + return glyphIndex; } -static inline size_t cocoa_bytes_for_characters( const char *string, size_t chars ) +static inline size_t cocoa_bytes_for_characters(const char *string, size_t chars) { - size_t offset = 0; - while (chars-- > 0) { - uint8_t ch = ((uint8_t *)string)[offset]; - - if (0xC2 <= ch && ch <= 0xDF) offset += 2; - else if (0xE0 <= ch && ch <= 0xEF) offset += 3; - else if (0xF0 <= ch && ch <= 0xF4) offset += 4; - else offset++; - } - return offset; + size_t offset = 0; + while (chars-- > 0) { + uint8_t ch = ((uint8_t *)string)[offset]; + + if (0xC2 <= ch && ch <= 0xDF) + offset += 2; + else if (0xE0 <= ch && ch <= 0xEF) + offset += 3; + else if (0xF0 <= ch && ch <= 0xF4) + offset += 4; + else + offset++; + } + return offset; } -static NSLayoutManager *cocoa_prepare_layout_manager( const char *bytes, size_t length, - const plot_font_style_t *style ) +static NSLayoutManager *cocoa_prepare_layout_manager(const char *bytes, size_t length, + const plot_font_style_t *style) { - if (NULL == bytes || 0 == length) return nil; - - NSString *string = [[NSString alloc] initWithBytes: bytes length:length encoding:NSUTF8StringEncoding] ; - if (string == nil) return nil; - - static NSLayoutManager *layout = nil; - if (nil == layout) { - cocoa_text_container = [[NSTextContainer alloc] initWithContainerSize: NSMakeSize( CGFLOAT_MAX, CGFLOAT_MAX )]; - [cocoa_text_container setLineFragmentPadding: 0]; - - layout = [[NSLayoutManager alloc] init]; - [layout addTextContainer: cocoa_text_container]; - } - - static NSString *oldString = 0; - static plot_font_style_t oldStyle = { 0, 0, 0, 0, 0, 0 }; - - const bool styleChanged = memcmp( style, &oldStyle, sizeof oldStyle ) != 0; - - if ([oldString isEqualToString: string] && !styleChanged) { - return layout; - } - - oldString = [string copy]; - oldStyle = *style; - - static NSDictionary *attributes = nil; - if (styleChanged || attributes == nil) { - attributes = cocoa_font_attributes( style ) ; - } - - cocoa_text_storage = [[NSTextStorage alloc] initWithString: string attributes: attributes]; - [cocoa_text_storage addLayoutManager: layout]; - - [layout ensureLayoutForTextContainer: cocoa_text_container]; - - return layout; + if (NULL == bytes || 0 == length) + return nil; + + NSString *string = [[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding]; + if (string == nil) + return nil; + + static NSLayoutManager *layout = nil; + if (nil == layout) { + cocoa_text_container = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)]; + [cocoa_text_container setLineFragmentPadding:0]; + + layout = [[NSLayoutManager alloc] init]; + [layout addTextContainer:cocoa_text_container]; + } + + static NSString *oldString = 0; + static plot_font_style_t oldStyle = { 0, 0, 0, 0, 0, 0 }; + + const bool styleChanged = memcmp(style, &oldStyle, sizeof oldStyle) != 0; + + if ([oldString isEqualToString:string] && !styleChanged) { + return layout; + } + + oldString = [string copy]; + oldStyle = *style; + + static NSDictionary *attributes = nil; + if (styleChanged || attributes == nil) { + attributes = cocoa_font_attributes(style); + } + + cocoa_text_storage = [[NSTextStorage alloc] initWithString:string attributes:attributes]; + [cocoa_text_storage addLayoutManager:layout]; + + [layout ensureLayoutForTextContainer:cocoa_text_container]; + + return layout; } -static NSString * const cocoa_font_families[PLOT_FONT_FAMILY_COUNT] = { - [PLOT_FONT_FAMILY_SERIF] = @"Times", - [PLOT_FONT_FAMILY_SANS_SERIF] = @"Helvetica", - [PLOT_FONT_FAMILY_MONOSPACE] = @"Courier", - [PLOT_FONT_FAMILY_CURSIVE] = @"Apple Chancery", - [PLOT_FONT_FAMILY_FANTASY] = @"Marker Felt" +static NSString *const cocoa_font_families[PLOT_FONT_FAMILY_COUNT] = { + [PLOT_FONT_FAMILY_SERIF] = @"Times", + [PLOT_FONT_FAMILY_SANS_SERIF] = @"Helvetica", + [PLOT_FONT_FAMILY_MONOSPACE] = @"Courier", + [PLOT_FONT_FAMILY_CURSIVE] = @"Apple Chancery", + [PLOT_FONT_FAMILY_FANTASY] = @"Marker Felt" }; -static inline NSFont *cocoa_font_get_nsfont( const plot_font_style_t *style ) +static inline NSFont *cocoa_font_get_nsfont(const plot_font_style_t *style) { - NSFont *font = [NSFont fontWithName: cocoa_font_families[style->family] - size: (CGFloat)style->size / FONT_SIZE_SCALE]; - - NSFontTraitMask traits = 0; - if (style->flags & FONTF_ITALIC || style->flags & FONTF_OBLIQUE) traits |= NSItalicFontMask; - if (style->flags & FONTF_SMALLCAPS) traits |= NSSmallCapsFontMask; - if (style->weight > 400) traits |= NSBoldFontMask; - - if (0 != traits) { - NSFontManager *fm = [NSFontManager sharedFontManager]; - font = [fm convertFont: font toHaveTrait: traits]; - } - - return font; + NSFont *font = [NSFont fontWithName:cocoa_font_families[style->family] + size:(CGFloat)style->size / FONT_SIZE_SCALE]; + + NSFontTraitMask traits = 0; + if (style->flags & FONTF_ITALIC || style->flags & FONTF_OBLIQUE) + traits |= NSItalicFontMask; + if (style->flags & FONTF_SMALLCAPS) + traits |= NSSmallCapsFontMask; + if (style->weight > 400) + traits |= NSBoldFontMask; + + if (0 != traits) { + NSFontManager *fm = [NSFontManager sharedFontManager]; + font = [fm convertFont:font toHaveTrait:traits]; + } + + return font; } -static inline NSDictionary *cocoa_font_attributes( const plot_font_style_t *style ) +static inline NSDictionary *cocoa_font_attributes(const plot_font_style_t *style) { - return [NSDictionary dictionaryWithObjectsAndKeys: - cocoa_font_get_nsfont( style ), NSFontAttributeName, - cocoa_convert_colour( style->foreground ), NSForegroundColorAttributeName, - nil]; + return [NSDictionary dictionaryWithObjectsAndKeys: + cocoa_font_get_nsfont(style), NSFontAttributeName, + cocoa_convert_colour(style->foreground), NSForegroundColorAttributeName, + nil]; } diff --git a/frontends/cocoa/gui.m b/frontends/cocoa/gui.m index 72f8e7afb..68411c98c 100644 --- a/frontends/cocoa/gui.m +++ b/frontends/cocoa/gui.m @@ -38,101 +38,96 @@ #import "cocoa/fetch.h" #import "cocoa/schedule.h" +NSString *const kCookiesFileOption = @"CookiesFile"; +NSString *const kURLsFileOption = @"URLsFile"; +NSString *const kHotlistFileOption = @"Hotlist"; +NSString *const kHomepageURLOption = @"HomepageURL"; +NSString *const kOptionsFileOption = @"ClassicOptionsFile"; +NSString *const kAlwaysCancelDownload = @"AlwaysCancelDownload"; +NSString *const kAlwaysCloseMultipleTabs = @"AlwaysCloseMultipleTabs"; -NSString * const kCookiesFileOption = @"CookiesFile"; -NSString * const kURLsFileOption = @"URLsFile"; -NSString * const kHotlistFileOption = @"Hotlist"; -NSString * const kHomepageURLOption = @"HomepageURL"; -NSString * const kOptionsFileOption = @"ClassicOptionsFile"; -NSString * const kAlwaysCancelDownload = @"AlwaysCancelDownload"; -NSString * const kAlwaysCloseMultipleTabs = @"AlwaysCloseMultipleTabs"; - -#define UNIMPL() NSLog( @"Function '%s' unimplemented", __func__ ) +#define UNIMPL() NSLog(@"Function '%s' unimplemented", __func__) struct browser_window; /* exported function docuemnted in cocoa/gui.h */ nserror cocoa_warning(const char *warning, const char *detail) { - NSRunAlertPanel( NSLocalizedString( @"Warning", - @"Warning title" ), - NSLocalizedString( @"Warning %s%s%s", - @"Warning message" ), - NSLocalizedString( @"OK", @"" ), nil, nil, - warning, detail != NULL ? ": " : "", - detail != NULL ? detail : "" ); - return NSERROR_OK; + NSRunAlertPanel(NSLocalizedString(@"Warning", + @"Warning title"), + NSLocalizedString(@"Warning %s%s%s", + @"Warning message"), + NSLocalizedString(@"OK", @""), nil, nil, + warning, detail != NULL ? ": " : "", + detail != NULL ? detail : ""); + return NSERROR_OK; } - static struct gui_window * gui_window_create(struct browser_window *bw, - struct gui_window *existing, - gui_window_create_flags flags) + struct gui_window *existing, + gui_window_create_flags flags) { - BrowserWindowController *window = nil; - BrowserViewController *result; - - browser_window_set_scale(bw, (float)nsoption_int(scale) / 100, false); - if (existing != NULL) { - window = [(__bridge BrowserViewController *)(existing) windowController]; - } - - result = [[BrowserViewController alloc] initWithBrowser: bw]; - - if (!(flags & GW_CREATE_TAB) || nil == window) { - window = [[BrowserWindowController alloc] init] ; - [[window window] makeKeyAndOrderFront: nil]; - } - [window addTab: result]; - - return (__bridge_retained struct gui_window *)result; + BrowserWindowController *window = nil; + BrowserViewController *result; + + browser_window_set_scale(bw, (float)nsoption_int(scale) / 100, false); + if (existing != NULL) { + window = [(__bridge BrowserViewController *)(existing)windowController]; + } + + result = [[BrowserViewController alloc] initWithBrowser:bw]; + + if (!(flags & GW_CREATE_TAB) || nil == window) { + window = [[BrowserWindowController alloc] init]; + [[window window] makeKeyAndOrderFront:nil]; + } + [window addTab:result]; + + return (__bridge_retained struct gui_window *)result; } static void gui_window_destroy(struct gui_window *g) { - BrowserViewController *vc = (__bridge_transfer BrowserViewController *)g; + BrowserViewController *vc = (__bridge_transfer BrowserViewController *)g; vc = nil; } static void gui_window_set_title(struct gui_window *g, const char *title) { - [(__bridge BrowserViewController *)g setTitle: [NSString stringWithUTF8String: title]]; + [(__bridge BrowserViewController *)g setTitle:[NSString stringWithUTF8String:title]]; } static nserror gui_window_update_box(struct gui_window *g, const struct rect *rect) { if (rect == NULL) { - [[(__bridge BrowserViewController *)g browserView] setNeedsDisplay: YES]; + [[(__bridge BrowserViewController *)g browserView] setNeedsDisplay:YES]; return NSERROR_OK; - } - const NSRect nsrect = cocoa_scaled_rect_wh( - browser_window_get_scale([(__bridge BrowserViewController *)g browser]), - rect->x0, rect->y0, - rect->x1 - rect->x0, rect->y1 - rect->y0 ); - [[(__bridge BrowserViewController *)g browserView] setNeedsDisplayInRect: nsrect]; - return NSERROR_OK; + const NSRect nsrect = cocoa_scaled_rect_wh( + browser_window_get_scale([(__bridge BrowserViewController *)g browser]), + rect->x0, rect->y0, + rect->x1 - rect->x0, rect->y1 - rect->y0); + [[(__bridge BrowserViewController *)g browserView] setNeedsDisplayInRect:nsrect]; + return NSERROR_OK; } static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) { - NSCParameterAssert( g != NULL && sx != NULL && sy != NULL ); - - NSRect visible = [[(__bridge BrowserViewController *)g browserView] visibleRect]; - *sx = cocoa_pt_to_px( NSMinX( visible ) ); - *sy = cocoa_pt_to_px( NSMinY( visible ) ); - return true; + NSCParameterAssert(g != NULL && sx != NULL && sy != NULL); + + NSRect visible = [[(__bridge BrowserViewController *)g browserView] visibleRect]; + *sx = cocoa_pt_to_px(NSMinX(visible)); + *sy = cocoa_pt_to_px(NSMinY(visible)); + return true; } static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect) { - [[(__bridge BrowserViewController *)g browserView] scrollPoint: cocoa_point( rect->x0, rect->y0 )]; - return 0; + [[(__bridge BrowserViewController *)g browserView] scrollPoint:cocoa_point(rect->x0, rect->y0)]; + return 0; } - - /** * Find the current dimensions of a cocoa browser window content area. * @@ -144,145 +139,144 @@ static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *re * else error code. */ static nserror gui_window_get_dimensions(struct gui_window *g, - int *width, int *height, - bool scaled) + int *width, int *height, + bool scaled) { - NSCParameterAssert( width != NULL && height != NULL ); - - NSRect frame = [[[(__bridge BrowserViewController *)g browserView] superview] frame]; - if (scaled) { - const CGFloat scale = browser_window_get_scale([(__bridge BrowserViewController *)g browser]); - frame.size.width /= scale; - frame.size.height /= scale; - } - *width = cocoa_pt_to_px( NSWidth( frame ) ); - *height = cocoa_pt_to_px( NSHeight( frame ) ); + NSCParameterAssert(width != NULL && height != NULL); - return NSERROR_OK; + NSRect frame = [[[(__bridge BrowserViewController *)g browserView] superview] frame]; + if (scaled) { + const CGFloat scale = browser_window_get_scale([(__bridge BrowserViewController *)g browser]); + frame.size.width /= scale; + frame.size.height /= scale; + } + *width = cocoa_pt_to_px(NSWidth(frame)); + *height = cocoa_pt_to_px(NSHeight(frame)); + + return NSERROR_OK; } static void gui_window_update_extent(struct gui_window *g) { - BrowserViewController * const window = (__bridge BrowserViewController *)g; - int width; - int height; - struct browser_window *browser = [window browser]; - - browser_window_get_extents(browser, false, &width, &height); - - [[window browserView] setMinimumSize: - cocoa_scaled_size( browser_window_get_scale(browser), width, height )]; + BrowserViewController *const window = (__bridge BrowserViewController *)g; + int width; + int height; + struct browser_window *browser = [window browser]; + + browser_window_get_extents(browser, false, &width, &height); + + [[window browserView] setMinimumSize: + cocoa_scaled_size(browser_window_get_scale(browser), width, height)]; } static void gui_window_set_status(struct gui_window *g, const char *text) { - [(__bridge BrowserViewController *)g setStatus: [NSString stringWithUTF8String: text]]; + [(__bridge BrowserViewController *)g setStatus:[NSString stringWithUTF8String:text]]; } static void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) { - switch (shape) { - case GUI_POINTER_DEFAULT: - case GUI_POINTER_WAIT: - case GUI_POINTER_PROGRESS: - [[NSCursor arrowCursor] set]; - break; - - case GUI_POINTER_CROSS: - [[NSCursor crosshairCursor] set]; - break; - - case GUI_POINTER_POINT: - case GUI_POINTER_MENU: - [[NSCursor pointingHandCursor] set]; - break; - - case GUI_POINTER_CARET: - [[NSCursor IBeamCursor] set]; - break; - - case GUI_POINTER_MOVE: - [[NSCursor closedHandCursor] set]; - break; - - default: - NSLog( @"Other cursor %d requested", shape ); - [[NSCursor arrowCursor] set]; - break; - } + switch (shape) { + case GUI_POINTER_DEFAULT: + case GUI_POINTER_WAIT: + case GUI_POINTER_PROGRESS: + [[NSCursor arrowCursor] set]; + break; + + case GUI_POINTER_CROSS: + [[NSCursor crosshairCursor] set]; + break; + + case GUI_POINTER_POINT: + case GUI_POINTER_MENU: + [[NSCursor pointingHandCursor] set]; + break; + + case GUI_POINTER_CARET: + [[NSCursor IBeamCursor] set]; + break; + + case GUI_POINTER_MOVE: + [[NSCursor closedHandCursor] set]; + break; + + default: + NSLog(@"Other cursor %d requested", shape); + [[NSCursor arrowCursor] set]; + break; + } } static nserror gui_window_set_url(struct gui_window *g, struct nsurl *url) { - [(__bridge BrowserViewController *)g setUrl: [NSString stringWithUTF8String: nsurl_access(url)]]; - return NSERROR_OK; + [(__bridge BrowserViewController *)g setUrl:[NSString stringWithUTF8String:nsurl_access(url)]]; + return NSERROR_OK; } static void gui_window_start_throbber(struct gui_window *g) { - [(__bridge BrowserViewController *)g setIsProcessing: YES]; - [(__bridge BrowserViewController *)g updateBackForward]; + [(__bridge BrowserViewController *)g setIsProcessing:YES]; + [(__bridge BrowserViewController *)g updateBackForward]; } static void gui_window_stop_throbber(struct gui_window *g) { - [(__bridge BrowserViewController *)g setIsProcessing: NO]; - [(__bridge BrowserViewController *)g updateBackForward]; + [(__bridge BrowserViewController *)g setIsProcessing:NO]; + [(__bridge BrowserViewController *)g updateBackForward]; } static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon) { - NSBitmapImageRep *bmp = NULL; - NSImage *image = nil; - - if (icon != NULL) { - bmp = (__bridge NSBitmapImageRep *)content_get_bitmap( icon ); - } - - if (bmp != nil) { - image = [[NSImage alloc] initWithSize: NSMakeSize( 32, 32 )]; - [image addRepresentation: bmp]; - } else { - image = [[NSImage imageNamed: @"NetSurf"] copy]; - } - [image setFlipped: YES]; - - [(__bridge BrowserViewController *)g setFavicon: image]; + NSBitmapImageRep *bmp = NULL; + NSImage *image = nil; + + if (icon != NULL) { + bmp = (__bridge NSBitmapImageRep *)content_get_bitmap(icon); + } + + if (bmp != nil) { + image = [[NSImage alloc] initWithSize:NSMakeSize(32, 32)]; + [image addRepresentation:bmp]; + } else { + image = [[NSImage imageNamed:@"NetSurf"] copy]; + } + [image setFlipped:YES]; + + [(__bridge BrowserViewController *)g setFavicon:image]; } static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, - const struct rect *clip) + const struct rect *clip) { - [[(__bridge BrowserViewController *)g browserView] - addCaretAt: cocoa_point( x, y ) - height: cocoa_px_to_pt( height )]; + [[(__bridge BrowserViewController *)g browserView] + addCaretAt:cocoa_point(x, y) + height:cocoa_px_to_pt(height)]; } static void gui_window_remove_caret(struct gui_window *g) { - [[(__bridge BrowserViewController *)g browserView] removeCaret]; + [[(__bridge BrowserViewController *)g browserView] removeCaret]; } static void gui_window_new_content(struct gui_window *g) { - [(__bridge BrowserViewController *)g contentUpdated]; + [(__bridge BrowserViewController *)g contentUpdated]; } - static void gui_create_form_select_menu(struct gui_window *g, - struct form_control *control) + struct form_control *control) { - BrowserViewController * const window = (__bridge BrowserViewController *)g; - FormSelectMenu *menu = [[FormSelectMenu alloc] - initWithControl: control - forWindow: [window browser]]; - [menu runInView: [window browserView]]; + BrowserViewController *const window = (__bridge BrowserViewController *)g; + FormSelectMenu *menu = [[FormSelectMenu alloc] + initWithControl:control + forWindow:[window browser]]; + [menu runInView:[window browserView]]; } static nserror gui_launch_url(nsurl *url) { - [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: [NSString stringWithUTF8String: nsurl_access(url)]]]; + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:nsurl_access(url)]]]; return NSERROR_OK; } @@ -290,45 +284,43 @@ struct ssl_cert_info; static nserror gui_cert_verify(nsurl *url, - const struct ssl_cert_info *certs, - unsigned long num, - nserror (*cb)(bool proceed,void *pw), void *cbpw) + const struct ssl_cert_info *certs, + unsigned long num, + nserror (*cb)(bool proceed, void *pw), void *cbpw) { - return NSERROR_NOT_IMPLEMENTED; + return NSERROR_NOT_IMPLEMENTED; } - static struct gui_window_table window_table = { - .create = gui_window_create, - .destroy = gui_window_destroy, - .invalidate = gui_window_update_box, - .get_scroll = gui_window_get_scroll, - .set_scroll = gui_window_set_scroll, - .get_dimensions = gui_window_get_dimensions, - .update_extent = gui_window_update_extent, - - .set_title = gui_window_set_title, - .set_url = gui_window_set_url, - .set_icon = gui_window_set_icon, - .set_status = gui_window_set_status, - .set_pointer = gui_window_set_pointer, - .place_caret = gui_window_place_caret, - .remove_caret = gui_window_remove_caret, - .new_content = gui_window_new_content, - .start_throbber = gui_window_start_throbber, - .stop_throbber = gui_window_stop_throbber, - .create_form_select_menu = gui_create_form_select_menu, + .create = gui_window_create, + .destroy = gui_window_destroy, + .invalidate = gui_window_update_box, + .get_scroll = gui_window_get_scroll, + .set_scroll = gui_window_set_scroll, + .get_dimensions = gui_window_get_dimensions, + .update_extent = gui_window_update_extent, + + .set_title = gui_window_set_title, + .set_url = gui_window_set_url, + .set_icon = gui_window_set_icon, + .set_status = gui_window_set_status, + .set_pointer = gui_window_set_pointer, + .place_caret = gui_window_place_caret, + .remove_caret = gui_window_remove_caret, + .new_content = gui_window_new_content, + .start_throbber = gui_window_start_throbber, + .stop_throbber = gui_window_stop_throbber, + .create_form_select_menu = gui_create_form_select_menu, }; struct gui_window_table *cocoa_window_table = &window_table; - static struct gui_misc_table browser_table = { - .schedule = cocoa_schedule, - .warning = cocoa_warning, + .schedule = cocoa_schedule, + .warning = cocoa_warning, - .launch_url = gui_launch_url, - .cert_verify = gui_cert_verify, + .launch_url = gui_launch_url, + .cert_verify = gui_cert_verify, }; struct gui_misc_table *cocoa_misc_table = &browser_table; diff --git a/frontends/cocoa/plotter.m b/frontends/cocoa/plotter.m index e4659ef80..f02f7727b 100644 --- a/frontends/cocoa/plotter.m +++ b/frontends/cocoa/plotter.m @@ -28,304 +28,306 @@ #import "cocoa/plotter.h" #import "cocoa/bitmap.h" -static void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle); -static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path,const plot_style_t *pstyle); -static inline void cocoa_center_pixel( bool x, bool y ); +static void cocoa_plot_render_path(NSBezierPath *path, const plot_style_t *pstyle); +static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path, const plot_style_t *pstyle); +static inline void cocoa_center_pixel(bool x, bool y); static NSRect cocoa_plot_clip_rect; -#define colour_red_component( c ) (((c) >> 0) & 0xFF) -#define colour_green_component( c ) (((c) >> 8) & 0xFF) -#define colour_blue_component( c ) (((c) >> 16) & 0xFF) -#define colour_alpha_component( c ) (((c) >> 24) & 0xFF) -#define colour_from_rgba( r, g, b, a) ((((colour)(r)) << 0) | \ - (((colour)(g)) << 8) | \ - (((colour)(b)) << 16) | \ - (((colour)(a)) << 24)) -#define colour_from_rgb( r, g, b ) colour_from_rgba( (r), (g), (b), 0xFF ) - -NSColor *cocoa_convert_colour( colour clr ) +#define colour_red_component(c) (((c) >> 0) & 0xFF) +#define colour_green_component(c) (((c) >> 8) & 0xFF) +#define colour_blue_component(c) (((c) >> 16) & 0xFF) +#define colour_alpha_component(c) (((c) >> 24) & 0xFF) +#define colour_from_rgba(r, g, b, a) ((((colour)(r)) << 0) | (((colour)(g)) << 8) | (((colour)(b)) << 16) | (((colour)(a)) << 24)) +#define colour_from_rgb(r, g, b) colour_from_rgba((r), (g), (b), 0xFF) + +NSColor *cocoa_convert_colour(colour clr) { - return [NSColor colorWithDeviceRed: (float)colour_red_component( clr ) / 0xFF - green: (float)colour_green_component( clr ) / 0xFF - blue: (float)colour_blue_component( clr ) / 0xFF - alpha: 1.0]; + return [NSColor colorWithDeviceRed:(float)colour_red_component(clr) / 0xFF + green:(float)colour_green_component(clr) / 0xFF + blue:(float)colour_blue_component(clr) / 0xFF + alpha:1.0]; } -static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path,const plot_style_t *pstyle) +static void cocoa_plot_path_set_stroke_pattern(NSBezierPath *path, const plot_style_t *pstyle) { - static const CGFloat dashed_pattern[2] = { 5.0, 2.0 }; - static const CGFloat dotted_pattern[2] = { 2.0, 2.0 }; - - switch (pstyle->stroke_type) { - case PLOT_OP_TYPE_DASH: - [path setLineDash: dashed_pattern count: 2 phase: 0]; - break; - - case PLOT_OP_TYPE_DOT: - [path setLineDash: dotted_pattern count: 2 phase: 0]; - break; - - default: - // ignore - break; - } - - [path setLineWidth: cocoa_px_to_pt( pstyle->stroke_width > 0 ? pstyle->stroke_width : 1 )]; + static const CGFloat dashed_pattern[2] = { 5.0, 2.0 }; + static const CGFloat dotted_pattern[2] = { 2.0, 2.0 }; + + switch (pstyle->stroke_type) { + case PLOT_OP_TYPE_DASH: + [path setLineDash:dashed_pattern count:2 phase:0]; + break; + + case PLOT_OP_TYPE_DOT: + [path setLineDash:dotted_pattern count:2 phase:0]; + break; + + default: + // ignore + break; + } + + [path setLineWidth:cocoa_px_to_pt(pstyle->stroke_width > 0 ? pstyle->stroke_width : 1)]; } static nserror plot_line(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *line) { - if (pstyle->stroke_type == PLOT_OP_TYPE_NONE) return true; - - [NSGraphicsContext saveGraphicsState]; - [NSBezierPath clipRect: cocoa_plot_clip_rect]; - - NSBezierPath *path = [NSBezierPath bezierPath]; - [path moveToPoint: cocoa_point( line->x0, line->y0 )]; - [path lineToPoint: cocoa_point( line->x1, line->y1 )]; - cocoa_plot_path_set_stroke_pattern( path, pstyle ); - - const bool horizontal = y0 == y1; - const bool vertical = line->x0 == line->x1; - const bool oddThickness = pstyle->stroke_width != 0 ? (pstyle->stroke_width % 2) != 0 : true; - - if (oddThickness) cocoa_center_pixel( !horizontal, !vertical ); - - [cocoa_convert_colour( pstyle->stroke_colour ) set]; - [path stroke]; - - [NSGraphicsContext restoreGraphicsState]; - - return NSERROR_OK; + if (pstyle->stroke_type == PLOT_OP_TYPE_NONE) + return true; + + [NSGraphicsContext saveGraphicsState]; + [NSBezierPath clipRect:cocoa_plot_clip_rect]; + + NSBezierPath *path = [NSBezierPath bezierPath]; + [path moveToPoint:cocoa_point(line->x0, line->y0)]; + [path lineToPoint:cocoa_point(line->x1, line->y1)]; + cocoa_plot_path_set_stroke_pattern(path, pstyle); + + const bool horizontal = y0 == y1; + const bool vertical = line->x0 == line->x1; + const bool oddThickness = pstyle->stroke_width != 0 ? (pstyle->stroke_width % 2) != 0 : true; + + if (oddThickness) + cocoa_center_pixel(!horizontal, !vertical); + + [cocoa_convert_colour(pstyle->stroke_colour) set]; + [path stroke]; + + [NSGraphicsContext restoreGraphicsState]; + + return NSERROR_OK; } static nserror plot_rectangle(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *r) { - NSRect rect = cocoa_rect( r->x0, r->y0, r->x1, r->y1 ); - NSBezierPath *path = [NSBezierPath bezierPathWithRect: rect]; - cocoa_plot_render_path( path, pstyle ); - - return NSERROR_OK; + NSRect rect = cocoa_rect(r->x0, r->y0, r->x1, r->y1); + NSBezierPath *path = [NSBezierPath bezierPathWithRect:rect]; + cocoa_plot_render_path(path, pstyle); + + return NSERROR_OK; } static nserror plot_text(const struct redraw_context *ctx, const plot_font_style_t *fstyle, int x, int y, const char *text, size_t length) { - [NSGraphicsContext saveGraphicsState]; - [NSBezierPath clipRect: cocoa_plot_clip_rect]; - - cocoa_draw_string( cocoa_px_to_pt( x ), cocoa_px_to_pt( y ), text, length, fstyle ); - - [NSGraphicsContext restoreGraphicsState]; - - return NSERROR_OK; + [NSGraphicsContext saveGraphicsState]; + [NSBezierPath clipRect:cocoa_plot_clip_rect]; + + cocoa_draw_string(cocoa_px_to_pt(x), cocoa_px_to_pt(y), text, length, fstyle); + + [NSGraphicsContext restoreGraphicsState]; + + return NSERROR_OK; } -void cocoa_set_clip( NSRect rect ) +void cocoa_set_clip(NSRect rect) { - cocoa_plot_clip_rect = rect; + cocoa_plot_clip_rect = rect; } static nserror plot_clip(const struct redraw_context *ctx, const struct rect *clip) { - cocoa_plot_clip_rect = cocoa_rect( clip->x0, clip->y0, clip->x1, clip->y1 ); - return NSERROR_OK; + cocoa_plot_clip_rect = cocoa_rect(clip->x0, clip->y0, clip->x1, clip->y1); + return NSERROR_OK; } -void cocoa_plot_render_path(NSBezierPath *path,const plot_style_t *pstyle) +void cocoa_plot_render_path(NSBezierPath *path, const plot_style_t *pstyle) { - [NSGraphicsContext saveGraphicsState]; - [NSBezierPath clipRect: cocoa_plot_clip_rect]; - - if (pstyle->fill_type != PLOT_OP_TYPE_NONE) { - [cocoa_convert_colour( pstyle->fill_colour ) setFill]; - [path fill]; - } - - if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) { - if (pstyle->stroke_width == 0 || pstyle->stroke_width % 2 != 0) cocoa_center_pixel( true, true ); - - cocoa_plot_path_set_stroke_pattern(path,pstyle); - - [cocoa_convert_colour( pstyle->stroke_colour ) set]; - - [path stroke]; - } - - [NSGraphicsContext restoreGraphicsState]; + [NSGraphicsContext saveGraphicsState]; + [NSBezierPath clipRect:cocoa_plot_clip_rect]; + + if (pstyle->fill_type != PLOT_OP_TYPE_NONE) { + [cocoa_convert_colour(pstyle->fill_colour) setFill]; + [path fill]; + } + + if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) { + if (pstyle->stroke_width == 0 || pstyle->stroke_width % 2 != 0) + cocoa_center_pixel(true, true); + + cocoa_plot_path_set_stroke_pattern(path, pstyle); + + [cocoa_convert_colour(pstyle->stroke_colour) set]; + + [path stroke]; + } + + [NSGraphicsContext restoreGraphicsState]; } static nserror plot_arc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius, int angle1, int angle2) { - NSBezierPath *path = [NSBezierPath bezierPath]; - [path appendBezierPathWithArcWithCenter: NSMakePoint( x, y ) radius: radius - startAngle: angle1 endAngle: angle2 - clockwise: NO]; - - cocoa_plot_render_path( path, pstyle); - - return NSERROR_OK; + NSBezierPath *path = [NSBezierPath bezierPath]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(x, y) + radius:radius + startAngle:angle1 + endAngle:angle2 + clockwise:NO]; + + cocoa_plot_render_path(path, pstyle); + + return NSERROR_OK; } static nserror plot_disc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius) { - NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect: - NSMakeRect( x - radius, y-radius, 2*radius, 2*radius )]; - - cocoa_plot_render_path( path, pstyle ); - - return NSERROR_OK; + NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect: + NSMakeRect(x - radius, y - radius, 2 * radius, 2 * radius)]; + + cocoa_plot_render_path(path, pstyle); + + return NSERROR_OK; } static nserror plot_polygon(const struct redraw_context *ctx, const plot_style_t *pstyle, const int *p, unsigned int n) { - if (n <= 1) return NSERROR_OK; - - NSBezierPath *path = [NSBezierPath bezierPath]; - [path moveToPoint: cocoa_point( p[0], p[1] )]; - for (unsigned i = 1; i < n; i++) { - [path lineToPoint: cocoa_point( p[2*i], p[2*i+1] )]; - } - [path closePath]; - - cocoa_plot_render_path( path, pstyle ); - - return NSERROR_OK; + if (n <= 1) + return NSERROR_OK; + + NSBezierPath *path = [NSBezierPath bezierPath]; + [path moveToPoint:cocoa_point(p[0], p[1])]; + for (unsigned i = 1; i < n; i++) { + [path lineToPoint:cocoa_point(p[2 * i], p[2 * i + 1])]; + } + [path closePath]; + + cocoa_plot_render_path(path, pstyle); + + return NSERROR_OK; } /* complex path (for SVG) */ static nserror plot_path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, float width, const float transform[6]) { - if (n == 0) return NSERROR_OK; - - if (*p != PLOTTER_PATH_MOVE) { - LOG("Path does not start with move"); - return NSERROR_INVALID; - } - - NSBezierPath *path = [NSBezierPath bezierPath]; + if (n == 0) + return NSERROR_OK; + + if (*p != PLOTTER_PATH_MOVE) { + LOG("Path does not start with move"); + return NSERROR_INVALID; + } + + NSBezierPath *path = [NSBezierPath bezierPath]; #define NEXT_POINT() ({ const float *c = p; p += 2; NSMakePoint( c[0], c[1] ); }) - - while (n--) { - switch ((int)*p++) { - case PLOTTER_PATH_MOVE: { - const NSPoint pt = NEXT_POINT(); - [path moveToPoint: pt]; - break; - } - - case PLOTTER_PATH_LINE: { - const NSPoint pt = NEXT_POINT(); - [path lineToPoint: pt]; - break; - } - - case PLOTTER_PATH_BEZIER: { - const NSPoint cp1 = NEXT_POINT(); - const NSPoint cp2 = NEXT_POINT(); - const NSPoint ep = NEXT_POINT(); - [path curveToPoint: ep controlPoint1: cp1 controlPoint2: cp2]; - break; - } - - case PLOTTER_PATH_CLOSE: - [path closePath]; - break; - - default: - LOG("Invalid path"); - return NSERROR_INVALID; - } - } - + + while (n--) { + switch ((int)*p++) { + case PLOTTER_PATH_MOVE: { + const NSPoint pt = NEXT_POINT(); + [path moveToPoint:pt]; + break; + } + + case PLOTTER_PATH_LINE: { + const NSPoint pt = NEXT_POINT(); + [path lineToPoint:pt]; + break; + } + + case PLOTTER_PATH_BEZIER: { + const NSPoint cp1 = NEXT_POINT(); + const NSPoint cp2 = NEXT_POINT(); + const NSPoint ep = NEXT_POINT(); + [path curveToPoint:ep controlPoint1:cp1 controlPoint2:cp2]; + break; + } + + case PLOTTER_PATH_CLOSE: + [path closePath]; + break; + + default: + LOG("Invalid path"); + return NSERROR_INVALID; + } + } + #undef NEXT_POINT - - [path setLineWidth: width]; - - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState( context ); - - CGContextClipToRect( context, NSRectToCGRect( cocoa_plot_clip_rect ) ); - - CGContextConcatCTM( context, CGAffineTransformMake( transform[0], transform[1], transform[2], - transform[3], transform[4], transform[5] ) ); - - if (pstyle->fill_colour != NS_TRANSPARENT) { - [cocoa_convert_colour(pstyle->fill_colour) setFill]; - [path fill]; - } - - if (pstyle->stroke_colour != NS_TRANSPARENT) { - cocoa_center_pixel( true, true ); - [cocoa_convert_colour( pstyle->stroke_colour ) set]; - [path stroke]; - } - - CGContextRestoreGState( context ); - - return true; + + [path setLineWidth:width]; + + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState(context); + + CGContextClipToRect(context, NSRectToCGRect(cocoa_plot_clip_rect)); + + CGContextConcatCTM(context, CGAffineTransformMake(transform[0], transform[1], transform[2], transform[3], transform[4], transform[5])); + + if (pstyle->fill_colour != NS_TRANSPARENT) { + [cocoa_convert_colour(pstyle->fill_colour) setFill]; + [path fill]; + } + + if (pstyle->stroke_colour != NS_TRANSPARENT) { + cocoa_center_pixel(true, true); + [cocoa_convert_colour(pstyle->stroke_colour) set]; + [path stroke]; + } + + CGContextRestoreGState(context); + + return true; } /* Image */ static nserror plot_bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags) { - CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState( context ); - - CGContextClipToRect( context, NSRectToCGRect( cocoa_plot_clip_rect ) ); - - const bool tileX = flags & BITMAPF_REPEAT_X; - const bool tileY = flags & BITMAPF_REPEAT_Y; - - CGImageRef img = cocoa_get_cgimage( bitmap ); - - CGRect rect = NSRectToCGRect( cocoa_rect_wh( x, y, width, height ) ); - - if (tileX || tileY) { - CGContextDrawTiledImage( context, rect, img ); - } else { - CGContextDrawImage( context, rect, img ); - } - - CGContextRestoreGState( context ); - - return NSERROR_OK; + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState(context); + + CGContextClipToRect(context, NSRectToCGRect(cocoa_plot_clip_rect)); + + const bool tileX = flags & BITMAPF_REPEAT_X; + const bool tileY = flags & BITMAPF_REPEAT_Y; + + CGImageRef img = cocoa_get_cgimage(bitmap); + + CGRect rect = NSRectToCGRect(cocoa_rect_wh(x, y, width, height)); + + if (tileX || tileY) { + CGContextDrawTiledImage(context, rect, img); + } else { + CGContextDrawImage(context, rect, img); + } + + CGContextRestoreGState(context); + + return NSERROR_OK; } const struct plotter_table cocoa_plotters = { - .clip = plot_clip, - .arc = plot_arc, - .disc = plot_disc, - .rectangle = plot_rectangle, - .line = plot_line, - .polygon = plot_polygon, - - .path = plot_path, - - .bitmap = plot_bitmap, - - .text = plot_text, - - .option_knockout = true -}; + .clip = plot_clip, + .arc = plot_arc, + .disc = plot_disc, + .rectangle = plot_rectangle, + .line = plot_line, + .polygon = plot_polygon, + + .path = plot_path, + .bitmap = plot_bitmap, + + .text = plot_text, + + .option_knockout = true +}; CGFloat cocoa_scale_factor; static const CGFloat points_per_inch = 72.0; static CGFloat cocoa_half_pixel; -void cocoa_update_scale_factor( void ) +void cocoa_update_scale_factor(void) { - const CGFloat scale = [[NSScreen mainScreen] backingScaleFactor]; - cocoa_scale_factor = scale == 1.0 ? 1.0 : 1.0 / scale; - cocoa_half_pixel = 0.5 * cocoa_scale_factor; - browser_set_dpi( points_per_inch * scale ); + const CGFloat scale = [[NSScreen mainScreen] backingScaleFactor]; + cocoa_scale_factor = scale == 1.0 ? 1.0 : 1.0 / scale; + cocoa_half_pixel = 0.5 * cocoa_scale_factor; + browser_set_dpi(points_per_inch * scale); } -static inline void cocoa_center_pixel( bool x, bool y ) +static inline void cocoa_center_pixel(bool x, bool y) { - NSAffineTransform *transform = [NSAffineTransform transform]; - [transform translateXBy: x ? cocoa_half_pixel : 0.0 yBy: y ? cocoa_half_pixel : 0.0]; - [transform concat]; + NSAffineTransform *transform = [NSAffineTransform transform]; + [transform translateXBy:x ? cocoa_half_pixel : 0.0 yBy:y ? cocoa_half_pixel : 0.0]; + [transform concat]; } diff --git a/frontends/cocoa/schedule.m b/frontends/cocoa/schedule.m index 65ca7f15d..0fc55efbd 100644 --- a/frontends/cocoa/schedule.m +++ b/frontends/cocoa/schedule.m @@ -23,55 +23,57 @@ #import "cocoa/schedule.h" @interface ScheduledCallback : NSObject { - void (*callback)( void *userData ); - void *userData; + void (*callback)(void *userData); + void *userData; } -- (instancetype)initWithCallback: (void (*)(void *))cb userData: (void *)ud; -- (void) schedule: (NSTimeInterval) ti; +- (instancetype)initWithCallback:(void (*)(void *))cb userData:(void *)ud; +- (void)schedule:(NSTimeInterval)ti; @end @implementation ScheduledCallback -- (instancetype)initWithCallback: (void (*)(void *))cb userData: (void *)ud +- (instancetype)initWithCallback:(void (*)(void *))cb userData:(void *)ud { - callback = cb; - userData = ud; - - return self; + callback = cb; + userData = ud; + + return self; } static NSMutableSet *timerSet = nil; -- (void) schedule: (NSTimeInterval) ti +- (void)schedule:(NSTimeInterval)ti { - if (nil == timerSet) { - timerSet = [[NSMutableSet alloc] init]; - } - - [self performSelector: @selector(timerFired) withObject: nil afterDelay: ti]; - [timerSet addObject: self]; + if (nil == timerSet) { + timerSet = [[NSMutableSet alloc] init]; + } + + [self performSelector:@selector(timerFired) withObject:nil afterDelay:ti]; + [timerSet addObject:self]; } -- (void) timerFired +- (void)timerFired { - if ([timerSet containsObject: self]) { - [timerSet removeObject: self]; - callback( userData ); - } + if ([timerSet containsObject:self]) { + [timerSet removeObject:self]; + callback(userData); + } } -- (BOOL) isEqual: (id)object +- (BOOL)isEqual:(id)object { - if (object == self) return YES; - if ([object class] != [self class]) return NO; - return ((ScheduledCallback *)object)->callback == callback && ((ScheduledCallback *)object)->userData == userData; + if (object == self) + return YES; + if ([object class] != [self class]) + return NO; + return ((ScheduledCallback *)object)->callback == callback && ((ScheduledCallback *)object)->userData == userData; } -- (NSUInteger) hash +- (NSUInteger)hash { - return (NSUInteger)callback + (NSUInteger)userData; + return (NSUInteger)callback + (NSUInteger)userData; } @end @@ -79,11 +81,11 @@ static NSMutableSet *timerSet = nil; /* exported interface documented in cocoa/schedule.h */ nserror cocoa_schedule(int t, void (*callback)(void *p), void *p) { - ScheduledCallback *cb = [[ScheduledCallback alloc] initWithCallback: callback userData: p]; - [timerSet removeObject: cb]; - if (t >= 0) { - [cb schedule: (NSTimeInterval)t / 1000]; - } + ScheduledCallback *cb = [[ScheduledCallback alloc] initWithCallback:callback userData:p]; + [timerSet removeObject:cb]; + if (t >= 0) { + [cb schedule:(NSTimeInterval)t / 1000]; + } - return NSERROR_OK; + return NSERROR_OK; } diff --git a/frontends/cocoa/selection.m b/frontends/cocoa/selection.m index 38dc9cf9f..58c645c4a 100644 --- a/frontends/cocoa/selection.m +++ b/frontends/cocoa/selection.m @@ -23,7 +23,6 @@ #import "netsurf/clipboard.h" - static NSMutableString *cocoa_clipboard_string; /** @@ -34,24 +33,24 @@ static NSMutableString *cocoa_clipboard_string; */ static void gui_get_clipboard(char **buffer, size_t *length) { - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - NSString *string = [pb stringForType: NSStringPboardType]; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + NSString *string = [pb stringForType:NSStringPboardType]; - *buffer = NULL; - *length = 0; + *buffer = NULL; + *length = 0; - if (string) { - const char *text = [string UTF8String]; - *length = strlen(text); + if (string) { + const char *text = [string UTF8String]; + *length = strlen(text); - *buffer = malloc(*length); + *buffer = malloc(*length); - if (*buffer != NULL) { - memcpy(*buffer, text, *length); - } else { - *length = 0; - } - } + if (*buffer != NULL) { + memcpy(*buffer, text, *length); + } else { + *length = 0; + } + } } /** @@ -63,40 +62,38 @@ static void gui_get_clipboard(char **buffer, size_t *length) * \param n_styles Number of text run styles in array */ static void gui_set_clipboard(const char *buffer, size_t length, - nsclipboard_styles styles[], int n_styles) + nsclipboard_styles styles[], int n_styles) { - /* Empty clipboard string */ - if (nil == cocoa_clipboard_string) { - cocoa_clipboard_string = [[NSMutableString alloc] init]; - } else { - [cocoa_clipboard_string setString: @""]; - } + /* Empty clipboard string */ + if (nil == cocoa_clipboard_string) { + cocoa_clipboard_string = [[NSMutableString alloc] init]; + } else { + [cocoa_clipboard_string setString:@""]; + } + + [cocoa_clipboard_string appendString:[[NSString alloc] + initWithBytes:buffer + length:length + encoding:NSUTF8StringEncoding]]; - - [cocoa_clipboard_string appendString: [[NSString alloc] - initWithBytes: buffer - length: length - encoding: NSUTF8StringEncoding] - ]; - - /* Stick it on the pasteboard */ - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - [pb declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil]; - bool result = [pb setString: cocoa_clipboard_string forType: NSStringPboardType]; + /* Stick it on the pasteboard */ + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; + bool result = [pb setString:cocoa_clipboard_string forType:NSStringPboardType]; - if (result) { - /* Empty clipboard string */ - if (nil == cocoa_clipboard_string) { - cocoa_clipboard_string = [[NSMutableString alloc] init]; - } else { - [cocoa_clipboard_string setString: @""]; - } - } + if (result) { + /* Empty clipboard string */ + if (nil == cocoa_clipboard_string) { + cocoa_clipboard_string = [[NSMutableString alloc] init]; + } else { + [cocoa_clipboard_string setString:@""]; + } + } } static struct gui_clipboard_table clipboard_table = { - .get = gui_get_clipboard, - .set = gui_set_clipboard, + .get = gui_get_clipboard, + .set = gui_set_clipboard, }; struct gui_clipboard_table *cocoa_clipboard_table = &clipboard_table; -- cgit v1.2.3