From: <ste...@us...> - 2007-05-25 21:57:26
|
Revision: 869 http://svn.sourceforge.net/vienna-rss/?rev=869&view=rev Author: stevewpalmer Date: 2007-05-25 14:57:27 -0700 (Fri, 25 May 2007) Log Message: ----------- First stage of 2.2 new global search feature. Revert the UI layout back to the 2.1 style for now. This has, unfortunately, broken the new PSMTabBarControl behaviour so we'll need to fix this asap. Modified Paths: -------------- trunk/2.2.0/ActivityViewer.h trunk/2.2.0/ActivityViewer.m trunk/2.2.0/AppController.h trunk/2.2.0/AppController.m trunk/2.2.0/ArticleListView.h trunk/2.2.0/ArticleListView.m trunk/2.2.0/CHANGES trunk/2.2.0/Database.m trunk/2.2.0/TODO trunk/2.2.0/Vienna.xcodeproj/project.pbxproj trunk/2.2.0/en.lproj/MainMenu.nib/classes.nib trunk/2.2.0/en.lproj/MainMenu.nib/info.nib trunk/2.2.0/en.lproj/MainMenu.nib/keyedobjects.nib Added Paths: ----------- trunk/2.2.0/SplitViewExtensions.h trunk/2.2.0/SplitViewExtensions.m trunk/2.2.0/columnIcon.tiff trunk/2.2.0/columnIconPressed.tiff Removed Paths: ------------- trunk/2.2.0/AMPolishedButton.h trunk/2.2.0/AMPolishedButton.m trunk/2.2.0/AMPolishedButtonCell.h trunk/2.2.0/AMPolishedButtonCell.m trunk/2.2.0/CTGradient.h trunk/2.2.0/CTGradient.m trunk/2.2.0/ContentSplitView.h trunk/2.2.0/ContentSplitView.m trunk/2.2.0/ContentSplitViewBar.tiff trunk/2.2.0/ContentSplitViewDimple.tiff trunk/2.2.0/GradientView.h trunk/2.2.0/GradientView.m trunk/2.2.0/KFSplitView.h trunk/2.2.0/KFSplitView.m trunk/2.2.0/PolishedPopupButton.h trunk/2.2.0/PolishedPopupButton.m trunk/2.2.0/PolishedWindow.h trunk/2.2.0/PolishedWindow.m trunk/2.2.0/SourceListSplitView.h trunk/2.2.0/SourceListSplitView.m trunk/2.2.0/bottom_left.png trunk/2.2.0/bottom_middle.png trunk/2.2.0/bottom_right.png trunk/2.2.0/button_disabled_left.png trunk/2.2.0/button_disabled_middle.png trunk/2.2.0/button_disabled_right.png trunk/2.2.0/button_normal_left.png trunk/2.2.0/button_normal_middle.png trunk/2.2.0/button_normal_right.png trunk/2.2.0/button_pressed_left.png trunk/2.2.0/button_pressed_middle.png trunk/2.2.0/button_pressed_right.png trunk/2.2.0/column_cornerview.png trunk/2.2.0/top_left.png trunk/2.2.0/top_middle.png trunk/2.2.0/top_right.png Deleted: trunk/2.2.0/AMPolishedButton.h =================================================================== --- trunk/2.2.0/AMPolishedButton.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AMPolishedButton.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,16 +0,0 @@ -// -// AMPolishedButton.h -// Polished Button -// -// Created by Andy Matuschak on 7/31/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#import <Cocoa/Cocoa.h> - - -@interface AMPolishedButton : NSButton { - -} - -@end Deleted: trunk/2.2.0/AMPolishedButton.m =================================================================== --- trunk/2.2.0/AMPolishedButton.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AMPolishedButton.m 2007-05-25 21:57:27 UTC (rev 869) @@ -1,51 +0,0 @@ -// -// AMPolishedButton.m -// Polished Button -// -// Created by Andy Matuschak on 7/31/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#import "AMPolishedButton.h" -#import "AMPolishedButtonCell.h" - -@interface AMPolishedButton (Private) -- (void)setupPolishedButton; -@end - -@implementation AMPolishedButton - -+ (Class)cellClass -{ - return [AMPolishedButtonCell class]; -} - -- initWithCoder:(NSCoder *)coder -{ - [super initWithCoder:coder]; - // For some reason, replacing the cell clobbers the button's enabled status, so we store it and reset it later. - BOOL enabled = [self isEnabled]; - [self setupPolishedButton]; - [self setEnabled:enabled]; - return self; -} - -- (void)setupPolishedButton -{ - AMPolishedButtonCell *cell = [AMPolishedButtonCell alloc]; - if ([[self cell] image] && [[self cell] imagePosition] != NSNoImage) - { - [cell initImageCell:[[self cell] image]]; - [cell setAlternateImage:[[self cell] image]]; - [cell setImagePosition:[[self cell] imagePosition]]; - } - else - { - [cell initTextCell:[self title]]; - } - [cell setButtonType:NSMomentaryChangeButton]; - [cell autorelease]; - [self setCell:cell]; -} - -@end Deleted: trunk/2.2.0/AMPolishedButtonCell.h =================================================================== --- trunk/2.2.0/AMPolishedButtonCell.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AMPolishedButtonCell.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,18 +0,0 @@ -// -// AMPolishedButtonCell.h -// Polished Button -// -// Created by Andy Matuschak on 7/31/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#import <Cocoa/Cocoa.h> - -// The button cell can use Core Image to make a bezel highlight for image cells. If you don't want to use Core Image, comment this out. -#define POLISHED_BUTTON_USES_CORE_IMAGE_BEZELS - -@interface AMPolishedButtonCell : NSButtonCell { - -} - -@end Deleted: trunk/2.2.0/AMPolishedButtonCell.m =================================================================== --- trunk/2.2.0/AMPolishedButtonCell.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AMPolishedButtonCell.m 2007-05-25 21:57:27 UTC (rev 869) @@ -1,134 +0,0 @@ -// -// AMPolishedButtonCell.m -// Polished Button -// -// Created by Andy Matuschak on 7/31/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#import "AMPolishedButtonCell.h" -#import <QuartzCore/QuartzCore.h> - -@interface AMPolishedButtonCell (Private) -- (void)setupAppearance; -- (void)drawImageWithFrame:(NSRect)frame inView:(NSButton *)view; -- (void)drawEmbossingHighlightForImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSButton *)view; -@end - -@implementation AMPolishedButtonCell - -- initWithCoder:(NSCoder *)coder -{ - [super initWithCoder:coder]; - [self setupAppearance]; - return self; -} - -- initTextCell:(NSString *)text -{ - [super initTextCell:text]; - [self setupAppearance]; - return self; -} - -- initImageCell:(NSImage *)image -{ - [super initImageCell:image]; - [self setupAppearance]; - return self; -} - -- (void)setupAppearance -{ - [self setFont:[NSFont boldSystemFontOfSize:11.5]]; -} - -- (BOOL)isOpaque -{ - return NO; -} - -- (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView*)view -{ - NSString *mode; - if ([self isHighlighted]) - mode = @"pressed"; - else if (![self isEnabled]) - mode = @"disabled"; - else - mode = @"normal"; - NSString *prefix = [NSString stringWithFormat:@"button_%@_", mode]; - - NSImage *left, *right, *middle; - left = [NSImage imageNamed:[prefix stringByAppendingString:@"left"]]; - middle = [NSImage imageNamed:[prefix stringByAppendingString:@"middle"]]; - right = [NSImage imageNamed:[prefix stringByAppendingString:@"right"]]; - [left setFlipped:[view isFlipped]]; - [middle setFlipped:[view isFlipped]]; - [right setFlipped:[view isFlipped]]; - - [left drawAtPoint:frame.origin fromRect:(NSRect){NSZeroPoint, [left size]} operation:NSCompositeSourceAtop fraction:1]; - [right drawAtPoint:NSMakePoint(NSMaxX(frame) - [right size].width, frame.origin.y) fromRect:(NSRect){NSZeroPoint, [right size]} operation:NSCompositeSourceAtop fraction:1]; - [middle drawInRect:NSMakeRect(frame.origin.x + [left size].width, frame.origin.y, frame.size.width - [left size].width - [right size].width, [middle size].height) fromRect:(NSRect){NSZeroPoint, [middle size]} operation:NSCompositeSourceAtop fraction:1]; -} - -- (void)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)view -{ - NSMutableAttributedString *string = [[[NSMutableAttributedString alloc] initWithAttributedString:title] autorelease]; - // First draw the white "embossing" string. - [string addAttributes:[NSMutableDictionary dictionaryWithObject:[NSColor colorWithCalibratedWhite:1 alpha:0.9] forKey:NSForegroundColorAttributeName] range:NSMakeRange(0, [string length])]; - [super drawTitle:string withFrame:frame inView:view]; - // Then draw the normal string on top. - [string addAttributes:[NSMutableDictionary dictionaryWithObject:[NSColor colorWithCalibratedWhite:0 alpha:([self isEnabled] ? 0.9 : 0.6)] forKey:NSForegroundColorAttributeName] range:NSMakeRange(0, [string length])]; - [super drawTitle:string withFrame:NSOffsetRect(frame, 0, ([view isFlipped] ? -1 : 1)) inView:view]; -} - -- (void)drawImageWithFrame:(NSRect)frame inView:(NSButton *)view -{ - NSImage *image; - if ([self isHighlighted] && [self alternateImage]) - image = [self alternateImage]; - else - image = [self image]; -#ifdef POLISHED_BUTTON_USES_CORE_IMAGE_BEZELS - [self drawEmbossingHighlightForImage:image withFrame:frame inView:view]; -#endif - [super drawImage:image withFrame:NSOffsetRect(frame, 0, ([view isFlipped] ? -1 : 1)) inView:view]; -} - -#ifdef POLISHED_BUTTON_USES_CORE_IMAGE_BEZELS -- (void)drawEmbossingHighlightForImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSButton *)view -{ - // Desaturate the image and pump up its brightness to get a good embossing highlight. - CIFilter *colorAdjust = [CIFilter filterWithName:@"CIColorControls"]; - [colorAdjust setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputSaturation"]; - [colorAdjust setValue:[NSNumber numberWithFloat:0.75] forKey:@"inputBrightness"]; - [colorAdjust setValue:[CIImage imageWithData:[image TIFFRepresentation]] forKey:@"inputImage"]; - CIImage *result = [colorAdjust valueForKey:@"outputImage"]; - - if ([view isFlipped]) - { - // CIImage doesn't have a setFlipped, so we need to flip it the long way. - CIFilter *transform = [CIFilter filterWithName:@"CIAffineTransform"]; - [transform setValue:result forKey:@"inputImage"]; - NSAffineTransform *affineTransform = [NSAffineTransform transform]; - [affineTransform translateXBy:0 yBy:[image size].height]; - [affineTransform scaleXBy:1 yBy:-1]; - [transform setValue:affineTransform forKey:@"inputTransform"]; - result = [transform valueForKey:@"outputImage"]; - } - - [result drawAtPoint:NSMakePoint(NSMidX(frame) - [image size].width / 2.0, NSMidY(frame) - [image size].width / 2.0) fromRect:(NSRect){NSZeroPoint, [image size]} operation:NSCompositeSourceAtop fraction:([self isEnabled] ? 0.6 : 0.4)]; -} -#endif - -- (void)drawWithFrame:(NSRect)frame inView:(NSButton *)view -{ - [self drawInteriorWithFrame:frame inView:view]; - if ([self image] && [self imagePosition] != NSNoImage) - [self drawImageWithFrame:frame inView:view]; - else - [self drawTitle:[view attributedTitle] withFrame:frame inView:view]; -} - -@end Modified: trunk/2.2.0/ActivityViewer.h =================================================================== --- trunk/2.2.0/ActivityViewer.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ActivityViewer.h 2007-05-25 21:57:27 UTC (rev 869) @@ -20,12 +20,11 @@ #import <Foundation/Foundation.h> #import "TableViewExtensions.h" -#import "KFSplitView.h" @interface ActivityViewer : NSWindowController { IBOutlet NSWindow * activityWindow; IBOutlet ExtendedTableView * activityTable; - IBOutlet KFSplitView * splitView; + IBOutlet NSSplitView * splitView; IBOutlet NSTextView * activityDetail; NSArray * allItems; } Modified: trunk/2.2.0/ActivityViewer.m =================================================================== --- trunk/2.2.0/ActivityViewer.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ActivityViewer.m 2007-05-25 21:57:27 UTC (rev 869) @@ -22,6 +22,7 @@ #import "ActivityLog.h" #import "AppController.h" #import "Preferences.h" +#import "SplitViewExtensions.h" @implementation ActivityViewer Modified: trunk/2.2.0/AppController.h =================================================================== --- trunk/2.2.0/AppController.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AppController.h 2007-05-25 21:57:27 UTC (rev 869) @@ -24,7 +24,6 @@ #import "ActivityViewer.h" #import "Growl/GrowlApplicationBridge.h" #import "DownloadWindow.h" -#import "KFSplitView.h" @class NewPreferenceController; @class FoldersTree; @@ -42,7 +41,7 @@ IBOutlet NSWindow * mainWindow; IBOutlet ArticleController * articleController; IBOutlet FoldersTree * foldersTree; - IBOutlet KFSplitView * splitView1; + IBOutlet NSSplitView * splitView1; IBOutlet NSView * exportSaveAccessory; IBOutlet ArticleListView * mainArticleView; IBOutlet UnifiedDisplayView * unifiedListView; Modified: trunk/2.2.0/AppController.m =================================================================== --- trunk/2.2.0/AppController.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/AppController.m 2007-05-25 21:57:27 UTC (rev 869) @@ -27,6 +27,7 @@ #import "Export.h" #import "RefreshManager.h" #import "StringExtensions.h" +#import "SplitViewExtensions.h" #import "BrowserView.h" #import "SearchFolder.h" #import "NewSubscription.h" @@ -289,6 +290,9 @@ previousArticleGuid = nil; [[articleController mainArticleView] selectFolderAndArticle:previousFolderId guid:previousArticleGuid]; + // Make article list the first responder + [mainWindow makeFirstResponder:[[browserView primaryTabItemView] mainView]]; + [self loadOpenTabs]; doneSafeInit = YES; } @@ -612,7 +616,7 @@ * Make sure the folder width isn't shrunk beyond a minimum width. Otherwise it looks * untidy. */ --(float)splitView:(KFSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset +-(float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset { return (sender == splitView1 && offset == 0) ? MA_Minimum_Folder_Pane_Width : proposedMin; } @@ -621,7 +625,7 @@ * Make sure that the browserview isn't shrunk beyond a minimum size otherwise the splitview * or controls within it start resizing odd. */ --(float)splitView:(KFSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset +-(float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset { if (sender == splitView1 && offset == 0) { @@ -634,7 +638,7 @@ /* resizeSubviewsWithOldSize * Constrain the folder pane to a fixed width. */ --(void)splitView:(KFSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize +-(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { float dividerThickness = [sender dividerThickness]; id sv1 = [[sender subviews] objectAtIndex:0]; Modified: trunk/2.2.0/ArticleListView.h =================================================================== --- trunk/2.2.0/ArticleListView.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ArticleListView.h 2007-05-25 21:57:27 UTC (rev 869) @@ -25,7 +25,6 @@ #import "ArticleBaseView.h" #import "BrowserView.h" #import "PopupButton.h" -#import "KFSplitView.h" @class AppController; @class ArticleController; @@ -41,9 +40,10 @@ IBOutlet TexturedHeader * articleListHeader; IBOutlet MessageListView * articleList; IBOutlet ArticleView * articleText; - IBOutlet KFSplitView * splitView2; + IBOutlet NSSplitView * splitView2; IBOutlet FoldersTree * foldersTree; IBOutlet PopupButton * filtersPopupMenu; + IBOutlet PopupButton * columnsPopupMenu; int currentSelectedRow; int tableLayout; Modified: trunk/2.2.0/ArticleListView.m =================================================================== --- trunk/2.2.0/ArticleListView.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ArticleListView.m 2007-05-25 21:57:27 UTC (rev 869) @@ -23,6 +23,7 @@ #import "Constants.h" #import "AppController.h" #import "ArticleController.h" +#import "SplitViewExtensions.h" #import "MessageListView.h" #import "ArticleView.h" #import "FoldersTree.h" @@ -150,7 +151,7 @@ * Make sure the article pane width isn't shrunk beyond a minimum width. Otherwise it looks * untidy. */ --(float)splitView:(KFSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset +-(float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset { return (sender == splitView2 && offset == 0) ? MA_Minimum_ArticleList_Pane_Width : proposedMin; } @@ -159,7 +160,7 @@ * Make sure that the article pane isn't shrunk beyond a minimum size otherwise the splitview * or controls within it start resizing odd. */ --(float)splitView:(KFSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset +-(float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset { if (sender == splitView2 && offset == 0) { @@ -174,7 +175,7 @@ /* resizeSubviewsWithOldSize * Constrain the article list pane to a fixed width. */ --(void)splitView:(KFSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize +-(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { float dividerThickness = [sender dividerThickness]; id sv1 = [[sender subviews] objectAtIndex:0]; @@ -319,16 +320,11 @@ [menuItem release]; } } - - NSRect buttonFrame = [[articleList cornerView] frame]; - PopupButton *button = [[PopupButton alloc] initWithFrame:buttonFrame]; - [button setBezelStyle:NSSmallSquareBezelStyle]; - [button setImage: [NSImage imageNamed:@"column_cornerview"]]; - [button setBordered:NO]; - [articleList setCornerView:button]; - [button setMenu:columnsSubMenu]; - [button release]; + // Set the columns popup on the title bar to show the same menu. + [columnsPopupMenu setMenu:columnsSubMenu]; + [columnsPopupMenu setSmallMenu:YES]; + [columnsPopupMenu setToolTip:NSLocalizedString(@"Select columns to display", nil)]; // Get the default list of visible columns [self updateVisibleColumns]; Modified: trunk/2.2.0/CHANGES =================================================================== --- trunk/2.2.0/CHANGES 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/CHANGES 2007-05-25 21:57:27 UTC (rev 869) @@ -22,6 +22,8 @@ - Added Basque localization. (Thanks to Aitor Zubizarreta). - If Vienna doesn't handle the URL scheme (e.g., itms), open the URL with the default application for its scheme. - Allow refreshing of unsubscribed feeds if they are specifically selected. (Thanks to ytrewq1 for submitting a patch.) +- Updated to SQLite 3.3.17. +- Change exported file format to UTF8. (Thanks to Kiyu Horiuti). 2.1.2.2110 ---------- Deleted: trunk/2.2.0/CTGradient.h =================================================================== --- trunk/2.2.0/CTGradient.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/CTGradient.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,66 +0,0 @@ -// -// CTGradient.h -// -// Created by Chad Weider on 12/3/05. -// Copyright (c) 2006 Cotingent. -// Some rights reserved: <http://creativecommons.org/licenses/by/2.5/> -// -// Version: 1.5 - -#import <Cocoa/Cocoa.h> - -typedef struct _CTGradientElement - { - float red, green, blue, alpha; - float position; - - struct _CTGradientElement *nextElement; - } CTGradientElement; - -typedef enum _CTBlendingMode - { - CTLinearBlendingMode, - CTChromaticBlendingMode, - CTInverseChromaticBlendingMode - } CTGradientBlendingMode; - - -@interface CTGradient : NSObject <NSCopying, NSCoding> - { - CTGradientElement* elementList; - CTGradientBlendingMode blendingMode; - - CGFunctionRef gradientFunction; - } - -+ (id)gradientWithBeginningColor:(NSColor *)begin endingColor:(NSColor *)end; - -+ (id)aquaSelectedGradient; -+ (id)aquaNormalGradient; -+ (id)aquaPressedGradient; - -+ (id)unifiedSelectedGradient; -+ (id)unifiedNormalGradient; -+ (id)unifiedPressedGradient; -+ (id)unifiedDarkGradient; - -+ (id)sourceListSelectedGradient; -+ (id)sourceListUnselectedGradient; - -- (CTGradient *)gradientWithAlphaComponent:(float)alpha; - -- (CTGradient *)addColorStop:(NSColor *)color atPosition:(float)position; //positions given relative to [0,1] -- (CTGradient *)removeColorStopAtIndex:(unsigned)index; -- (CTGradient *)removeColorStopAtPosition:(float)position; - -- (CTGradientBlendingMode)blendingMode; -- (NSColor *)colorStopAtIndex:(unsigned)index; -- (NSColor *)colorAtPosition:(float)position; - - -- (void)drawSwatchInRect:(NSRect)rect; -- (void)fillRect:(NSRect)rect angle:(float)angle; //fills rect with axial gradient - // angle in degrees -- (void)radialFillRect:(NSRect)rect; //fills rect with radial gradient - // gradient from center outwards -@end Deleted: trunk/2.2.0/CTGradient.m =================================================================== --- trunk/2.2.0/CTGradient.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/CTGradient.m 2007-05-25 21:57:27 UTC (rev 869) @@ -1,1231 +0,0 @@ -// -// CTGradient.m -// -// Created by Chad Weider on 12/3/05. -// Copyright (c) 2006 Cotingent. -// Some rights reserved: <http://creativecommons.org/licenses/by/2.5/> -// -// Version: 1.5 - -#import "CTGradient.h" - -@interface CTGradient (Private) -- (void)_commonInit; -- (void)setBlendingMode:(CTGradientBlendingMode)mode; -- (void)addElement:(CTGradientElement*)newElement; - -- (CTGradientElement *)elementAtIndex:(unsigned)index; - -- (CTGradientElement)removeElementAtIndex:(unsigned)index; -- (CTGradientElement)removeElementAtPosition:(float)position; -@end - -//C Fuctions for color blending -void linearEvaluation (void *info, const float *in, float *out); -void chromaticEvaluation(void *info, const float *in, float *out); -void inverseChromaticEvaluation(void *info, const float *in, float *out); -void transformRGB_HSV(float *components); -void transformHSV_RGB(float *components); -void resolveHSV(float *color1, float *color2); - - -@implementation CTGradient -/////////////////////////////////////Initialization Type Stuff -- (id)init - { - self = [super init]; - - if (self != nil) - { - [self _commonInit]; - [self setBlendingMode:CTLinearBlendingMode]; - } - return self; - } - -- (void)_commonInit - { - elementList = nil; - } - -- (void)dealloc - { - CGFunctionRelease(gradientFunction); - - CTGradientElement *elementToRemove = elementList; - while(elementList != nil) - { - elementToRemove = elementList; - elementList = elementList->nextElement; - free(elementToRemove); - } - - [super dealloc]; - } - -- (id)copyWithZone:(NSZone *)zone - { - CTGradient *copy = [[[self class] allocWithZone:zone] init]; - - //now just copy my elementlist - CTGradientElement *currentElement = elementList; - while(currentElement != nil) - { - [copy addElement:currentElement]; - currentElement = currentElement->nextElement; - } - - [copy setBlendingMode:blendingMode]; - - return copy; - } - -- (void)encodeWithCoder:(NSCoder *)coder - { - if([coder allowsKeyedCoding]) - { - unsigned count = 0; - CTGradientElement *currentElement = elementList; - while(currentElement != nil) - { - [coder encodeValueOfObjCType:@encode(float) at:&(currentElement->red)]; - [coder encodeValueOfObjCType:@encode(float) at:&(currentElement->green)]; - [coder encodeValueOfObjCType:@encode(float) at:&(currentElement->blue)]; - [coder encodeValueOfObjCType:@encode(float) at:&(currentElement->alpha)]; - [coder encodeValueOfObjCType:@encode(float) at:&(currentElement->position)]; - - count++; - currentElement = currentElement->nextElement; - } - [coder encodeInt:count forKey:@"CTGradientElementCount"]; - [coder encodeInt:blendingMode forKey:@"CTGradientBlendingMode"]; - } - else - [NSException raise:NSInvalidArchiveOperationException format:@"Only supports NSKeyedArchiver coders"]; - } - -- (id)initWithCoder:(NSCoder *)coder - { - [self _commonInit]; - - [self setBlendingMode:[coder decodeIntForKey:@"CTGradientBlendingMode"]]; - unsigned count = [coder decodeIntForKey:@"CTGradientElementCount"]; - - while(count != 0) - { - CTGradientElement newElement; - - [coder decodeValueOfObjCType:@encode(float) at:&(newElement.red)]; - [coder decodeValueOfObjCType:@encode(float) at:&(newElement.green)]; - [coder decodeValueOfObjCType:@encode(float) at:&(newElement.blue)]; - [coder decodeValueOfObjCType:@encode(float) at:&(newElement.alpha)]; - [coder decodeValueOfObjCType:@encode(float) at:&(newElement.position)]; - - count--; - [self addElement:&newElement]; - } - return self; - } - - -#pragma mark - - - - -#pragma mark Creation -+ (id)gradientWithBeginningColor:(NSColor *)begin endingColor:(NSColor *)end - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - CTGradientElement color2; - - [[begin colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&color1.red - green:&color1.green - blue:&color1.blue - alpha:&color1.alpha]; - - [[end colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&color2.red - green:&color2.green - blue:&color2.blue - alpha:&color2.alpha]; - color1.position = 0; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)aquaSelectedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = 0.58; - color1.green = 0.86; - color1.blue = 0.98; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = 0.42; - color2.green = 0.68; - color2.blue = 0.90; - color2.alpha = 1.00; - color2.position = 11.5/23; - - CTGradientElement color3; - color3.red = 0.64; - color3.green = 0.80; - color3.blue = 0.94; - color3.alpha = 1.00; - color3.position = 11.5/23; - - CTGradientElement color4; - color4.red = 0.56; - color4.green = 0.70; - color4.blue = 0.90; - color4.alpha = 1.00; - color4.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - [newInstance addElement:&color3]; - [newInstance addElement:&color4]; - - return [newInstance autorelease]; - } - -+ (id)aquaNormalGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.95; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.83; - color2.alpha = 1.00; - color2.position = 11.5/23; - - CTGradientElement color3; - color3.red = color3.green = color3.blue = 0.95; - color3.alpha = 1.00; - color3.position = 11.5/23; - - CTGradientElement color4; - color4.red = color4.green = color4.blue = 0.92; - color4.alpha = 1.00; - color4.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - [newInstance addElement:&color3]; - [newInstance addElement:&color4]; - - return [newInstance autorelease]; - } - -+ (id)aquaPressedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.80; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.64; - color2.alpha = 1.00; - color2.position = 11.5/23; - - CTGradientElement color3; - color3.red = color3.green = color3.blue = 0.80; - color3.alpha = 1.00; - color3.position = 11.5/23; - - CTGradientElement color4; - color4.red = color4.green = color4.blue = 0.77; - color4.alpha = 1.00; - color4.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - [newInstance addElement:&color3]; - [newInstance addElement:&color4]; - - return [newInstance autorelease]; - } - -+ (id)unifiedSelectedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.85; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.95; - color2.alpha = 1.00; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)unifiedNormalGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.75; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.90; - color2.alpha = 1.00; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)unifiedPressedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.60; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.75; - color2.alpha = 1.00; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)unifiedDarkGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = color1.green = color1.blue = 0.40; - color1.alpha = 1.00; - color1.position = 0.15; - - CTGradientElement color2; - color2.red = color2.green = color2.blue = 0.80; - color2.alpha = 1.00; - color2.position = 1.0; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)sourceListSelectedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = 0.06; - color1.green = 0.37; - color1.blue = 0.85; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = 0.30; - color2.green = 0.60; - color2.blue = 0.92; - color2.alpha = 1.00; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)sourceListUnselectedGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = 0.43; - color1.green = 0.43; - color1.blue = 0.43; - color1.alpha = 1.00; - color1.position = 0; - - CTGradientElement color2; - color2.red = 0.60; - color2.green = 0.60; - color2.blue = 0.60; - color2.alpha = 1.00; - color2.position = 1; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - return [newInstance autorelease]; - } - -+ (id)rainbowGradient - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement color1; - color1.red = 1.00; - color1.green = 0.00; - color1.blue = 0.00; - color1.alpha = 1.00; - color1.position = 0.0; - - CTGradientElement color2; - color2.red = 0.54; - color2.green = 0.00; - color2.blue = 1.00; - color2.alpha = 1.00; - color2.position = 1.0; - - [newInstance addElement:&color1]; - [newInstance addElement:&color2]; - - [newInstance setBlendingMode:CTChromaticBlendingMode]; - - return [newInstance autorelease]; - } - -+ (id)hydrogenSpectrumGradient - { - id newInstance = [[[self class] alloc] init]; - - struct {float hue; float position; float width;} colorBands[4]; - - colorBands[0].hue = 22; - colorBands[0].position = .145; - colorBands[0].width = .01; - - colorBands[1].hue = 200; - colorBands[1].position = .71; - colorBands[1].width = .008; - - colorBands[2].hue = 253; - colorBands[2].position = .885; - colorBands[2].width = .005; - - colorBands[3].hue = 275; - colorBands[3].position = .965; - colorBands[3].width = .003; - - int i; - ///////////////////////////// - for(i = 0; i < 4; i++) - { - float color[4]; - color[0] = colorBands[i].hue - 180*colorBands[i].width; - color[1] = 1; - color[2] = 0.001; - color[3] = 1; - transformHSV_RGB(color); - CTGradientElement fadeIn; - fadeIn.red = color[0]; - fadeIn.green = color[1]; - fadeIn.blue = color[2]; - fadeIn.alpha = color[3]; - fadeIn.position = colorBands[i].position - colorBands[i].width; - - - color[0] = colorBands[i].hue; - color[1] = 1; - color[2] = 1; - color[3] = 1; - transformHSV_RGB(color); - CTGradientElement band; - band.red = color[0]; - band.green = color[1]; - band.blue = color[2]; - band.alpha = color[3]; - band.position = colorBands[i].position; - - color[0] = colorBands[i].hue + 180*colorBands[i].width; - color[1] = 1; - color[2] = 0.001; - color[3] = 1; - transformHSV_RGB(color); - CTGradientElement fadeOut; - fadeOut.red = color[0]; - fadeOut.green = color[1]; - fadeOut.blue = color[2]; - fadeOut.alpha = color[3]; - fadeOut.position = colorBands[i].position + colorBands[i].width; - - - [newInstance addElement:&fadeIn]; - [newInstance addElement:&band]; - [newInstance addElement:&fadeOut]; - } - - [newInstance setBlendingMode:CTChromaticBlendingMode]; - - return [newInstance autorelease]; - } - -#pragma mark - - - - -#pragma mark Modification -- (CTGradient *)gradientWithAlphaComponent:(float)alpha - { - id newInstance = [[[self class] alloc] init]; - - CTGradientElement *curElement = elementList; - CTGradientElement tempElement; - - while(curElement != nil) - { - tempElement = *curElement; - tempElement.alpha = alpha; - [newInstance addElement:&tempElement]; - - curElement = curElement->nextElement; - } - - return [newInstance autorelease]; - } - -- (CTGradient *)gradientWithBlendingMode:(CTGradientBlendingMode)mode - { - CTGradient *newGradient = [self copy]; - - [newGradient setBlendingMode:mode]; - - return [newGradient autorelease]; - } - - -//Adds a color stop with <color> at <position> in elementList -//(if two elements are at the same position then added imediatly after the one that was there already) -- (CTGradient *)addColorStop:(NSColor *)color atPosition:(float)position - { - CTGradient *newGradient = [self copy]; - CTGradientElement newGradientElement; - - //put the components of color into the newGradientElement - must make sure it is a RGB color (not Gray or CMYK) - [[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getRed:&newGradientElement.red - green:&newGradientElement.green - blue:&newGradientElement.blue - alpha:&newGradientElement.alpha]; - newGradientElement.position = position; - - //Pass it off to addElement to take care of adding it to the elementList - [newGradient addElement:&newGradientElement]; - - return [newGradient autorelease]; - } - - -//Removes the color stop at <position> from elementList -- (CTGradient *)removeColorStopAtPosition:(float)position - { - CTGradient *newGradient = [self copy]; - CTGradientElement removedElement = [newGradient removeElementAtPosition:position]; - - if(isnan(removedElement.position)) - [NSException raise:NSRangeException format:@"-[%@ removeColorStopAtPosition:]: no such colorStop at position (%f)", [self class], position]; - - return [newGradient autorelease]; - } - -- (CTGradient *)removeColorStopAtIndex:(unsigned)index - { - CTGradient *newGradient = [self copy]; - CTGradientElement removedElement = [newGradient removeElementAtIndex:index]; - - if(isnan(removedElement.position)) - [NSException raise:NSRangeException format:@"-[%@ removeColorStopAtIndex:]: index (%i) beyond bounds", [self class], index]; - - return [newGradient autorelease]; - } -#pragma mark - - - - -#pragma mark Information -- (CTGradientBlendingMode)blendingMode - { - return blendingMode; - } - -//Returns color at <position> in gradient -- (NSColor *)colorStopAtIndex:(unsigned)index - { - CTGradientElement *element = [self elementAtIndex:index]; - - if(element != nil) - return [NSColor colorWithCalibratedRed:element->red - green:element->green - blue:element->blue - alpha:element->alpha]; - - [NSException raise:NSRangeException format:@"-[%@ removeColorStopAtIndex:]: index (%i) beyond bounds", [self class], index]; - - return nil; - } - -- (NSColor *)colorAtPosition:(float)position - { - float components[4]; - - switch(blendingMode) - { - case CTLinearBlendingMode: - linearEvaluation(&elementList, &position, components); break; - case CTChromaticBlendingMode: - chromaticEvaluation(&elementList, &position, components); break; - case CTInverseChromaticBlendingMode: - inverseChromaticEvaluation(&elementList, &position, components); break; - } - - - return [NSColor colorWithCalibratedRed:components[0] - green:components[1] - blue:components[2] - alpha:components[3]]; - } -#pragma mark - - - - -#pragma mark Drawing -- (void)drawSwatchInRect:(NSRect)rect - { - [self fillRect:rect angle:45]; - } - -- (void)fillRect:(NSRect)rect angle:(float)angle - { - //First Calculate where the beginning and ending points should be - CGPoint startPoint; - CGPoint endPoint; - - if(angle == 0) //screw the calculations - we know the answer - { - startPoint = CGPointMake(NSMinX(rect), NSMinY(rect)); //right of rect - endPoint = CGPointMake(NSMaxX(rect), NSMinY(rect)); //left of rect - } - else if(angle == 90) //same as above - { - startPoint = CGPointMake(NSMinX(rect), NSMinY(rect)); //bottom of rect - endPoint = CGPointMake(NSMinX(rect), NSMaxY(rect)); //top of rect - } - else //ok, we'll do the calculations now - { - float x,y; - float sina, cosa, tana; - - float length; - float deltax, - deltay; - - float rangle = angle * pi/180; //convert the angle to radians - - if(fabsf(tan(rangle))<=1) //for range [-45,45], [135,225] - { - x = NSWidth(rect); - y = NSHeight(rect); - - sina = sin(rangle); - cosa = cos(rangle); - tana = tan(rangle); - - length = x/fabsf(cosa)+(y-x*fabsf(tana))*fabsf(sina); - - deltax = length*cosa/2; - deltay = length*sina/2; - } - else //for range [45,135], [225,315] - { - x = NSHeight(rect); - y = NSWidth(rect); - - sina = sin(rangle - 90*pi/180); - cosa = cos(rangle - 90*pi/180); - tana = tan(rangle - 90*pi/180); - - length = x/fabsf(cosa)+(y-x*fabsf(tana))*fabsf(sina); - - deltax =-length*sina/2; - deltay = length*cosa/2; - } - - startPoint = CGPointMake(NSMidX(rect)-deltax, NSMidY(rect)-deltay); - endPoint = CGPointMake(NSMidX(rect)+deltax, NSMidY(rect)+deltay); - } - - //Calls to CoreGraphics - CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState(currentContext); - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - #else - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - #endif - - CGShadingRef myCGShading = CGShadingCreateAxial(colorspace, startPoint, endPoint, gradientFunction, false, false); - - CGContextClipToRect(currentContext , *(CGRect *)&rect); //This is where the action happens - CGContextDrawShading(currentContext, myCGShading); - - CGShadingRelease (myCGShading); - CGColorSpaceRelease(colorspace ); - CGContextRestoreGState(currentContext); - } - -- (void)radialFillRect:(NSRect)rect - { - CGPoint startPoint , endPoint; - float startRadius, endRadius; - - startPoint = endPoint = CGPointMake(NSMidX(rect), NSMidY(rect)); - - startRadius = 1; - - if(NSHeight(rect)>NSWidth(rect)) - endRadius = NSHeight(rect)/2; - else - endRadius = NSWidth(rect)/2; - - //Calls to CoreGraphics - CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState(currentContext); - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - #else - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - #endif - - CGShadingRef myCGShading = CGShadingCreateRadial(colorspace, startPoint, startRadius, endPoint, endRadius, gradientFunction, true, true); - - CGContextClipToRect (currentContext , *(CGRect *)&rect); - CGContextDrawShading(currentContext , myCGShading); //This is where the action happens - - CGShadingRelease (myCGShading); - CGColorSpaceRelease (colorspace); - CGContextRestoreGState(currentContext); - } - -#pragma mark - - - - -#pragma mark Private Methods -- (void)setBlendingMode:(CTGradientBlendingMode)mode; - { - blendingMode = mode; - - //Choose what blending function to use - void *evaluationFunction = nil; - switch(blendingMode) - { - case CTLinearBlendingMode: - evaluationFunction = &linearEvaluation; break; - case CTChromaticBlendingMode: - evaluationFunction = &chromaticEvaluation; break; - case CTInverseChromaticBlendingMode: - evaluationFunction = &inverseChromaticEvaluation; break; - } - - //replace the current CoreGraphics Function with new one - if(gradientFunction != NULL) - CGFunctionRelease(gradientFunction); - - CGFunctionCallbacks evaluationCallbackInfo = {0 , evaluationFunction, NULL}; //Version, evaluator function, cleanup function - - static const float input_value_range [2] = { 0, 1 }; //range for the evaluator input - static const float output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; //ranges for the evaluator output (4 returned values) - - gradientFunction = CGFunctionCreate(&elementList, //the two transition colors - 1, input_value_range , //number of inputs (just fraction of progression) - 4, output_value_ranges, //number of outputs (4 - RGBa) - &evaluationCallbackInfo); //info for using the evaluator function - } - -- (void)addElement:(CTGradientElement *)newElement -{ - if(elementList == nil || newElement->position < elementList->position) //inserting at beginning of list - { - CTGradientElement *tmpNext = elementList; - elementList = malloc(sizeof(CTGradientElement)); - *elementList = *newElement; - elementList->nextElement = tmpNext; - } - else //inserting somewhere inside list - { - CTGradientElement *curElement = elementList; - - while(curElement->nextElement != nil && !((curElement->position <= newElement->position) && (newElement->position < curElement->nextElement->position))) - { - curElement = curElement->nextElement; - } - - CTGradientElement *tmpNext = curElement->nextElement; - curElement->nextElement = malloc(sizeof(CTGradientElement)); - *(curElement->nextElement) = *newElement; - curElement->nextElement->nextElement = tmpNext; - } - } - -- (CTGradientElement)removeElementAtIndex:(unsigned)index - { - CTGradientElement removedElement; - - if(elementList != nil) - { - if(index == 0) - { - CTGradientElement *tmpNext = elementList; - elementList = elementList->nextElement; - - removedElement = *tmpNext; - free(tmpNext); - - return removedElement; - } - - unsigned count = 1; //we want to start one ahead - CTGradientElement *currentElement = elementList; - while(currentElement->nextElement != nil) - { - if(count == index) - { - CTGradientElement *tmpNext = currentElement->nextElement; - currentElement->nextElement = currentElement->nextElement->nextElement; - - removedElement = *tmpNext; - free(tmpNext); - - return removedElement; - } - - count++; - currentElement = currentElement->nextElement; - } - } - - //element is not found, return empty element - removedElement.red = 0.0; - removedElement.green = 0.0; - removedElement.blue = 0.0; - removedElement.alpha = 0.0; - removedElement.position = NAN; - removedElement.nextElement = nil; - - return removedElement; - } - -- (CTGradientElement)removeElementAtPosition:(float)position - { - CTGradientElement removedElement; - - if(elementList != nil) - { - if(elementList->position == position) - { - CTGradientElement *tmpNext = elementList; - elementList = elementList->nextElement; - - removedElement = *tmpNext; - free(tmpNext); - - return removedElement; - } - else - { - CTGradientElement *curElement = elementList; - while(curElement->nextElement != nil) - { - if(curElement->nextElement->position == position) - { - CTGradientElement *tmpNext = curElement->nextElement; - curElement->nextElement = curElement->nextElement->nextElement; - - removedElement = *tmpNext; - free(tmpNext); - - return removedElement; - } - } - } - } - - //element is not found, return empty element - removedElement.red = 0.0; - removedElement.green = 0.0; - removedElement.blue = 0.0; - removedElement.alpha = 0.0; - removedElement.position = NAN; - removedElement.nextElement = nil; - - return removedElement; - } - - -- (CTGradientElement *)elementAtIndex:(unsigned)index; - { - unsigned count = 0; - CTGradientElement *currentElement = elementList; - - while(currentElement != nil) - { - if(count == index) - return currentElement; - - count++; - currentElement = currentElement->nextElement; - } - - return nil; - } -#pragma mark - - - - -#pragma mark Core Graphics -//////////////////////////////////////Blending Functions///////////////////////////////////// -void linearEvaluation (void *info, const float *in, float *out) - { - float position = *in; - - if(*(CTGradientElement **)info == nil) //if elementList is empty return clear color - { - out[0] = out[1] = out[2] = out[3] = 1; - return; - } - - //This grabs the first two colors in the sequence - CTGradientElement *color1 = *(CTGradientElement **)info; - CTGradientElement *color2 = color1->nextElement; - - //make sure first color and second color are on other sides of position - while(color2 != nil && color2->position < position) - { - color1 = color2; - color2 = color1->nextElement; - } - //if we don't have another color then make next color the same color - if(color2 == nil) - { - color2 = color1; - } - - //----------FailSafe settings---------- - //color1->red = 1; color2->red = 0; - //color1->green = 1; color2->green = 0; - //color1->blue = 1; color2->blue = 0; - //color1->alpha = 1; color2->alpha = 1; - //color1->position = .5; - //color2->position = .5; - //------------------------------------- - - if(position <= color1->position) //Make all below color color1's position equal to color1 - { - out[0] = color1->red; - out[1] = color1->green; - out[2] = color1->blue; - out[3] = color1->alpha; - } - else if (position >= color2->position) //Make all above color color2's position equal to color2 - { - out[0] = color2->red; - out[1] = color2->green; - out[2] = color2->blue; - out[3] = color2->alpha; - } - else //Interpolate color at postions between color1 and color1 - { - //adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position - position = (position-color1->position)/(color2->position - color1->position); - - out[0] = (color2->red - color1->red )*position + color1->red; - out[1] = (color2->green - color1->green)*position + color1->green; - out[2] = (color2->blue - color1->blue )*position + color1->blue; - out[3] = (color2->alpha - color1->alpha)*position + color1->alpha; - } - } - - - - -//Chromatic Evaluation - -// This blends colors by their Hue, Saturation, and Value(Brightness) right now I just -// transform the RGB values stored in the CTGradientElements to HSB, in the future I may -// streamline it to avoid transforming in and out of HSB colorspace *for later* -// -// For the chromatic blend we shift the hue of color1 to meet the hue of color2. To do -// this we will add to the hue's angle (if we subtract we'll be doing the inverse -// chromatic...scroll down more for that). All we need to do is keep adding to the hue -// until we wrap around the colorwheel and get to color2. -void chromaticEvaluation(void *info, const float *in, float *out) - { - float position = *in; - - if(*(CTGradientElement **)info == nil) //if elementList is empty return clear color - { - out[0] = out[1] = out[2] = out[3] = 1; - return; - } - - //This grabs the first two colors in the sequence - CTGradientElement *color1 = *(CTGradientElement **)info; - CTGradientElement *color2 = color1->nextElement; - - float c1[4]; - float c2[4]; - - //make sure first color and second color are on other sides of position - while(color2 != nil && color2->position < position) - { - color1 = color2; - color2 = color1->nextElement; - } - //if we don't have another color then make next color the same color - if(color2 == nil) - { - color2 = color1; - } - - - c1[0] = color1->red; - c1[1] = color1->green; - c1[2] = color1->blue; - c1[3] = color1->alpha; - - c2[0] = color2->red; - c2[1] = color2->green; - c2[2] = color2->blue; - c2[3] = color2->alpha; - - transformRGB_HSV(c1); - transformRGB_HSV(c2); - resolveHSV(c1,c2); - - if(c1[0] > c2[0]) //if color1's hue is higher than color2's hue then - c2[0] += 360; // we need to move c2 one revolution around the wheel - - - if(position <= color1->position) //Make all below color color1's position equal to color1 - { - out[0] = c1[0]; - out[1] = c1[1]; - out[2] = c1[2]; - out[3] = c1[3]; - } - else if (position >= color2->position) //Make all above color color2's position equal to color2 - { - out[0] = c2[0]; - out[1] = c2[1]; - out[2] = c2[2]; - out[3] = c2[3]; - } - else //Interpolate color at postions between color1 and color1 - { - //adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position - position = (position-color1->position)/(color2->position - color1->position); - - out[0] = (c2[0] - c1[0])*position + c1[0]; - out[1] = (c2[1] - c1[1])*position + c1[1]; - out[2] = (c2[2] - c1[2])*position + c1[2]; - out[3] = (c2[3] - c1[3])*position + c1[3]; - } - - transformHSV_RGB(out); - - //if(position > -1 && out[0] == out[1] && out[1] == out[2] && out[0]==0) - //printf("%.4f: %.4f,%.4f,%.4f\n",position,out[0],out[1],out[2]); - //printf("%.4f: %.4f,%.4f,%.4f\n",position,color1->red,color1->green,color1->blue); - } - - - -//Inverse Chromatic Evaluation - -// Inverse Chromatic is about the same story as Chromatic Blend, but here the Hue -// is strictly decreasing, that is we need to get from color1 to color2 by decreasing -// the 'angle' (i.e. 90\xBC -> 180\xBC would be done by subtracting 270\xBC and getting -180\xBC... -// which is equivalent to 180\xBC mod 360\xBC -void inverseChromaticEvaluation(void *info, const float *in, float *out) - { - float position = *in; - - if(*(CTGradientElement **)info == nil) //if elementList is empty return clear color - { - out[0] = out[1] = out[2] = out[3] = 1; - return; - } - - //This grabs the first two colors in the sequence - CTGradientElement *color1 = *(CTGradientElement **)info; - CTGradientElement *color2 = color1->nextElement; - - float c1[4]; - float c2[4]; - - //make sure first color and second color are on other sides of position - while(color2 != nil && color2->position < position) - { - color1 = color2; - color2 = color1->nextElement; - } - //if we don't have another color then make next color the same color - if(color2 == nil) - { - color2 = color1; - } - - c1[0] = color1->red; - c1[1] = color1->green; - c1[2] = color1->blue; - c1[3] = color1->alpha; - - c2[0] = color2->red; - c2[1] = color2->green; - c2[2] = color2->blue; - c2[3] = color2->alpha; - - transformRGB_HSV(c1); - transformRGB_HSV(c2); - resolveHSV(c1,c2); - - if(c1[0] < c2[0]) //if color1's hue is higher than color2's hue then - c1[0] += 360; // we need to move c2 one revolution back on the wheel - - - if(position <= color1->position) //Make all below color color1's position equal to color1 - { - out[0] = c1[0]; - out[1] = c1[1]; - out[2] = c1[2]; - out[3] = c1[3]; - } - else if (position >= color2->position) //Make all above color color2's position equal to color2 - { - out[0] = c2[0]; - out[1] = c2[1]; - out[2] = c2[2]; - out[3] = c2[3]; - } - else //Interpolate color at postions between color1 and color1 - { - //adjust position so that it goes from 0 to 1 in the range from color 1 & 2's position - position = (position-color1->position)/(color2->position - color1->position); - - out[0] = (c2[0] - c1[0])*position + c1[0]; - out[1] = (c2[1] - c1[1])*position + c1[1]; - out[2] = (c2[2] - c1[2])*position + c1[2]; - out[3] = (c2[3] - c1[3])*position + c1[3]; - } - - transformHSV_RGB(out); - } - - - - - - - - - - -void transformRGB_HSV(float *components) //H,S,B -> R,G,B - { - float H, S, V; - float R = components[0], - G = components[1], - B = components[2]; - - float MAX = R > G ? (R > B ? R : B) : (G > B ? G : B), - MIN = R < G ? (R < B ? R : B) : (G < B ? G : B); - - if(MAX == MIN) - H = NAN; - else if(MAX == R) - if(G >= B) - H = 60*(G-B)/(MAX-MIN)+0; - else - H = 60*(G-B)/(MAX-MIN)+360; - else if(MAX == G) - H = 60*(B-R)/(MAX-MIN)+120; - else if(MAX == B) - H = 60*(R-G)/(MAX-MIN)+240; - else - H = NAN; - - S = MAX == 0 ? 0 : 1 - MIN/MAX; - V = MAX; - - components[0] = H; - components[1] = S; - components[2] = V; - } - -void transformHSV_RGB(float *components) //H,S,B -> R,G,B - { - float R = 0.0, G = 0.0, B = 0.0; - float H = fmodf(components[0],359), //map to [0,360) - S = components[1], - V = components[2]; - - int Hi = (int)floorf(H/60.) % 6; - float f = H/60-Hi, - p = V*(1-S), - q = V*(1-f*S), - t = V*(1-(1-f)*S); - - switch (Hi) - { - case 0: R=V;G=t;B=p; break; - case 1: R=q;G=V;B=p; break; - case 2: R=p;G=V;B=t; break; - case 3: R=p;G=q;B=V; break; - case 4: R=t;G=p;B=V; break; - case 5: R=V;G=p;B=q; break; - } - - components[0] = R; - components[1] = G; - components[2] = B; - } - -void resolveHSV(float *color1, float *color2) //H value may be undefined (i.e. graycale color) - { // we want to fill it with a sensible value - if(isnan(color1[0]) && isnan(color2[0])) - color1[0] = color2[0] = 0; - else if(isnan(color1[0])) - color1[0] = color2[0]; - else if(isnan(color2[0])) - color2[0] = color1[0]; - } - -@end Deleted: trunk/2.2.0/ContentSplitView.h =================================================================== --- trunk/2.2.0/ContentSplitView.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ContentSplitView.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,26 +0,0 @@ -// -// ContentSplitView.m -// -// Created by Dave Batton, August 2006. -// http://www.Mere-Mortal-Software.com/ -// -// Changes by Michael Stroeck on February 11, 2007. -// -// Copyright 2006 by Dave Batton. Some rights reserved. -// http://creativecommons.org/licenses/by/2.5/ -// -// This class draws a horizontal splitter like the one seen in Apple Mail (Tiger), below the message list and above the message detail view. -// It subclasses KFSplitView from Ken Ferry so that the splitter remembers where it was last left. It also allows the splitter to expand and -// collapse when double-clicked. The splitter thickness is reduced a bit and a background image and dimple are drawn in the splitter. -// -// Assumes the ContentSplitViewBar and ContentSplitViewDimple images are available. - -#import <Cocoa/Cocoa.h> -#import "KFSplitView.h" - -@interface ContentSplitView : KFSplitView { - NSImage *bar; - NSImage *grip; - id bottomSubview; -} -@end Deleted: trunk/2.2.0/ContentSplitView.m =================================================================== --- trunk/2.2.0/ContentSplitView.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/ContentSplitView.m 2007-05-25 21:57:27 UTC (rev 869) @@ -1,72 +0,0 @@ -// -// ContentSplitView.m -// -// Created by Dave Batton, August 2006. -// http://www.Mere-Mortal-Software.com/ -// -// Changes by Michael Stroeck on February 11, 2007. -// -// Copyright 2006 by Dave Batton. Some rights reserved. -// http://creativecommons.org/licenses/by/2.5/ -// -// This class draws a horizontal splitter like the one seen in Apple Mail (Tiger), below the message list and above the message detail view. -// It subclasses KFSplitView from Ken Ferry so that the splitter remembers where it was last left. It also allows the splitter to expand and -// collapse when double-clicked. The splitter thickness is reduced a bit and a background image and dimple are drawn in the splitter. -// -// Assumes the ContentSplitViewBar and ContentSplitViewDimple images are available. -// - -#define MIN_TOP_VIEW_HEIGHT 90 -#define MIN_BOTTOM_VIEW_HEIGHT 60 -#define DIVIDER_BAR_THICKNESS 8 - -#import "ContentSplitView.h" - -@implementation ContentSplitView - -/* awakeFromNib - */ --(void)awakeFromNib -{ - [self setDelegate:self]; - - bar = [NSImage imageNamed:@"ContentSplitViewBar.tiff"]; - [bar setFlipped:YES]; - - grip = [NSImage imageNamed:@"ContentSplitViewDimple.tiff"]; - [grip setFlipped:YES]; -} - -/* dividerThickness - * Returns the thickness of the divider bar. - */ --(float)dividerThickness -{ - return DIVIDER_BAR_THICKNESS; -} - -/* drawDividerInRect - * Draws the divider bar. - */ --(void)drawDividerInRect:(NSRect)aRect -{ - // Create a canvas - NSImage * canvas = [[[NSImage alloc] initWithSize:aRect.size] autorelease]; - - // Draw bar and grip onto the canvas - NSRect canvasRect = NSMakeRect(0, 0, [canvas size].width, [canvas size].height); - NSRect gripRect = canvasRect; - gripRect.origin.x = (NSMidX(canvasRect) - ([grip size].width / 2)); - gripRect.origin.y = (NSMidY(canvasRect) - ([grip size].height / 2)); - [canvas lockFocus]; - [bar setSize:aRect.size]; - [bar drawInRect:canvasRect fromRect:canvasRect operation:NSCompositeSourceOver fraction:1.0]; - [grip drawInRect:gripRect fromRect:canvasRect operation:NSCompositeSourceOver fraction:1.0]; - [canvas unlockFocus]; - - // Draw canvas to divider bar - [self lockFocus]; - [canvas drawInRect:aRect fromRect:canvasRect operation:NSCompositeSourceOver fraction:1.0]; - [self unlockFocus]; -} -@end \ No newline at end of file Deleted: trunk/2.2.0/ContentSplitViewBar.tiff =================================================================== (Binary files differ) Deleted: trunk/2.2.0/ContentSplitViewDimple.tiff =================================================================== (Binary files differ) Modified: trunk/2.2.0/Database.m =================================================================== --- trunk/2.2.0/Database.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/Database.m 2007-05-25 21:57:27 UTC (rev 869) @@ -814,7 +814,7 @@ } } } - + // Here we create the folder anew. int newItemId = [self createFolderOnDatabase:name underParent:parentId withType:type]; if (newItemId != -1) Deleted: trunk/2.2.0/GradientView.h =================================================================== --- trunk/2.2.0/GradientView.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/GradientView.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,16 +0,0 @@ -// -// GradientView.h -// Vienna -// -// Created by Michael Stroeck on 06.02.07. -// Copyright 2007 Michael Stroeck. All rights reserved. -// - -#import <Cocoa/Cocoa.h> - - -@interface GradientView : NSView { - -} - -@end Deleted: trunk/2.2.0/GradientView.m =================================================================== --- trunk/2.2.0/GradientView.m 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/GradientView.m 2007-05-25 21:57:27 UTC (rev 869) @@ -1,28 +0,0 @@ -// -// GradientView.m -// Vienna -// -// Created by Michael Stroeck on 06.02.07. -// Copyright 2007 Michael Stroeck. All rights reserved. -// - -#import "GradientView.h" -#import "CTGradient.h" - -@implementation GradientView - -- (id)initWithFrame:(NSRect)frame -{ - self = [super initWithFrame:frame]; - return self; -} - -- (void)drawRect:(NSRect)rect -{ - NSColor *topColor = [NSColor whiteColor]; - NSColor *bottomColor = [NSColor grayColor]; - CTGradient *gradient = [CTGradient gradientWithBeginningColor:topColor - endingColor:bottomColor]; - [gradient fillRect:[self bounds] angle:270]; -} -@end Deleted: trunk/2.2.0/KFSplitView.h =================================================================== --- trunk/2.2.0/KFSplitView.h 2007-05-21 02:59:02 UTC (rev 868) +++ trunk/2.2.0/KFSplitView.h 2007-05-25 21:57:27 UTC (rev 869) @@ -1,73 +0,0 @@ -// -// KFSplitView.h -// KFSplitView v. 1.3, 11/27/2004 -// -// Copyright (c) 2003-2004 Ken Ferry. Some rights reserved. -// http://homepage.mac.com/kenferry/software.html -// -// This work is licensed under a Creative Commons license: -// http://creativecommons.org/licenses/by-nc/1.0/ -// -// Send me an email if you have a... [truncated message content] |