source: trunk/Cocoa/Pester/Source/NSImage-OAExtensions.m @ 555

Last change on this file since 555 was 555, checked in by Nicholas Riley, 10 years ago

Fix (unimportant, in practice) retain leak in Omni NSImage extension.

File size: 7.5 KB
Line 
1// Copyright 1997-2002 Omni Development, Inc.  All rights reserved.
2//
3// This software may only be used and reproduced according to the
4// terms in the file OmniSourceLicense.html, which should be
5// distributed with this project and can also be found at
6// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.
7
8#import "NSImage-OAExtensions.h"
9
10#import <AppKit/AppKit.h>
11
12// RCS_ID("$Header: /Network/Source/CVS/OmniGroup/Frameworks/OmniAppKit/OpenStepExtensions.subproj/NSImage-OAExtensions.m,v 1.17 2002/03/09 01:53:54 kc Exp $")
13
14@implementation NSImage (OAExtensions)
15
16+ (NSImage *)imageNamed:(NSString *)imageName inBundleForClass:(Class)aClass;
17{
18    return [self imageNamed:imageName inBundle:[NSBundle bundleForClass:aClass]];
19}
20
21+ (NSImage *)imageNamed:(NSString *)imageName inBundle:(NSBundle *)aBundle;
22{
23    NSImage *image;
24    NSString *path;
25
26    image = [self imageNamed:imageName];
27    if (image && [image size].width != 0)
28        return image;
29
30    path = [aBundle pathForImageResource:imageName];
31    if (!path)
32        return nil;
33
34    image = [[NSImage alloc] initWithContentsOfFile:path];
35    [image setName:imageName];
36
37    return [image autorelease];
38}
39
40+ (NSImage *)imageForFileType:(NSString *)fileType;
41    // It turns out that -[NSWorkspace iconForFileType:] doesn't cache previously returned values, so we cache them here.
42{
43    static NSMutableDictionary *imageDictionary = nil;
44    id image;
45
46    // ASSERT_IN_MAIN_THREAD(@"+imageForFileType: is not thread-safe; must be called from the main thread");
47    // We could fix this by adding locks around imageDictionary
48
49    if (!fileType)
50        return nil;
51       
52    if (imageDictionary == nil)
53        imageDictionary = [[NSMutableDictionary alloc] init];
54
55    image = [imageDictionary objectForKey:fileType];
56    if (image == nil) {
57#ifdef DEBUG
58        // Make sure that our caching doesn't go insane (and that we don't ask it to cache insane stuff)
59        NSLog(@"Caching workspace image for file type '%@'", fileType);
60#endif
61        image = [[NSWorkspace sharedWorkspace] iconForFileType:fileType];
62        if (image == nil)
63            image = [NSNull null];
64        [imageDictionary setObject:image forKey:fileType];
65    }
66    return image != [NSNull null] ? image : nil;
67}
68
69#define X_SPACE_BETWEEN_ICON_AND_TEXT_BOX 2
70#define X_TEXT_BOX_BORDER 2
71#define Y_TEXT_BOX_BORDER 2
72static NSDictionary *titleFontAttributes;
73
74+ (NSImage *)draggingIconWithTitle:(NSString *)title andImage:(NSImage *)image;
75{
76    NSImage *drawImage;
77    NSSize imageSize, totalSize;
78    NSSize titleSize, titleBoxSize;
79    NSRect titleBox;
80    NSPoint textPoint;
81
82    NSParameterAssert(image != nil);
83    imageSize = [image size];
84
85    if (!titleFontAttributes)
86        titleFontAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSFont systemFontOfSize:12.0], NSFontAttributeName, [NSColor textColor], NSForegroundColorAttributeName, nil];
87
88    if (!title || [title length] == 0)
89        return image;
90   
91    titleSize = [title sizeWithAttributes:titleFontAttributes];
92    titleBoxSize = NSMakeSize(titleSize.width + 2.0 * X_TEXT_BOX_BORDER, titleSize.height + Y_TEXT_BOX_BORDER);
93
94    totalSize = NSMakeSize(imageSize.width + X_SPACE_BETWEEN_ICON_AND_TEXT_BOX + titleBoxSize.width, MAX(imageSize.height, titleBoxSize.height));
95
96    drawImage = [[NSImage alloc] initWithSize:totalSize];
97    [drawImage setFlipped:YES];
98
99    [drawImage lockFocus];
100
101    // Draw transparent background
102    [[NSColor colorWithDeviceWhite:1.0 alpha:0.0] set];
103    NSRectFill(NSMakeRect(0, 0, totalSize.width, totalSize.height));
104
105    // Draw icon
106    [image compositeToPoint:NSMakePoint(0.0, rint(totalSize.height / 2.0 + imageSize.height / 2.0)) operation:NSCompositeSourceOver];
107   
108    // Draw box around title
109    titleBox = NSMakeRect(imageSize.width + X_SPACE_BETWEEN_ICON_AND_TEXT_BOX, floor((totalSize.height - titleBoxSize.height)/2.0), titleBoxSize.width, titleBoxSize.height);
110    [[[NSColor selectedTextBackgroundColor] colorWithAlphaComponent:0.5] set];
111    NSRectFill(titleBox);
112
113    // Draw title
114    textPoint = NSMakePoint(imageSize.width + X_SPACE_BETWEEN_ICON_AND_TEXT_BOX + X_TEXT_BOX_BORDER, Y_TEXT_BOX_BORDER - 1);
115
116    [title drawAtPoint:textPoint withAttributes:titleFontAttributes];
117
118    [drawImage unlockFocus];
119
120    return [drawImage autorelease];
121}
122
123//
124
125- (void)drawFlippedInRect:(NSRect)rect operation:(NSCompositingOperation)op fraction:(float)delta;
126{
127    CGContextRef context;
128
129    context = [[NSGraphicsContext currentContext] graphicsPort];
130    CGContextSaveGState(context); {
131        CGContextTranslateCTM(context, 0, NSMaxY(rect));
132        CGContextScaleCTM(context, 1, -1);
133       
134        rect.origin.y = 0; // We've translated ourselves so it's zero
135        [self drawInRect:rect fromRect:NSZeroRect operation:op fraction:delta];
136    } CGContextRestoreGState(context);
137
138    /*
139        NSAffineTransform *flipTransform;
140        NSPoint transformedPoint;
141        NSSize transformedSize;
142        NSRect transformedRect;
143
144        flipTransform = [[NSAffineTransform alloc] init];
145        [flipTransform scaleXBy:1.0 yBy:-1.0];
146
147        transformedPoint = [flipTransform transformPoint:rect.origin];
148        transformedSize = [flipTransform transformSize:rect.size];
149        [flipTransform concat];
150        transformedRect = NSMakeRect(transformedPoint.x, transformedPoint.y + transformedSize.height, transformedSize.width, -transformedSize.height);
151        [anImage drawInRect:transformedRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
152        [flipTransform concat];
153        [flipTransform release];
154        */
155}
156
157- (void)drawFlippedInRect:(NSRect)rect operation:(NSCompositingOperation)op;
158{
159    [self drawFlippedInRect:rect operation:op fraction:1.0];
160}
161
162- (int)addDataToPasteboard:(NSPasteboard *)aPasteboard exceptTypes:(NSMutableSet *)notThese
163{
164    NSArray *myRepresentations;
165    int repIndex, repCount;
166    int count = 0;
167
168    if (!notThese)
169        notThese = [NSMutableSet set];
170
171#define IF_ADD(typename, dataOwner) if( ![notThese containsObject:(typename)] && [aPasteboard addTypes:[NSArray arrayWithObject:(typename)] owner:(dataOwner)] > 0 )
172
173#define ADD_CHEAP_DATA(typename, expr) IF_ADD(typename, nil) { [aPasteboard setData:(expr) forType:(typename)]; [notThese addObject:(typename)]; count ++; }
174       
175    /* If we have image representations lying around that already have data in some concrete format, add that data to the pasteboard. */
176    myRepresentations = [self representations];
177    repCount = [myRepresentations count];
178    for(repIndex = 0; repIndex < repCount; repIndex ++) {
179        NSImageRep *aRep = [myRepresentations objectAtIndex:repIndex];
180           
181        if ([aRep respondsToSelector:@selector(PDFRepresentation)]) {
182            ADD_CHEAP_DATA(NSPDFPboardType, [(NSPDFImageRep *)aRep PDFRepresentation]);
183        }
184
185        if ([aRep respondsToSelector:@selector(PICTRepresentation)]) {
186            ADD_CHEAP_DATA(NSPICTPboardType, [(NSPICTImageRep *)aRep PICTRepresentation]);
187        }
188
189        if ([aRep respondsToSelector:@selector(EPSRepresentation)]) {
190            ADD_CHEAP_DATA(NSPostScriptPboardType, [(NSEPSImageRep *)aRep EPSRepresentation]);
191        }
192    }
193   
194    /* Always offer to convert to TIFF. Do this lazily, though, since we probably have to extract it from a bitmap image rep. */
195    IF_ADD(NSTIFFPboardType, self) {
196        count ++;
197    }
198
199    return count;
200}
201
202- (void)pasteboard:(NSPasteboard *)aPasteboard provideDataForType:(NSString *)wanted
203{
204    if ([wanted isEqual:NSTIFFPboardType]) {
205        [aPasteboard setData:[self TIFFRepresentation] forType:NSTIFFPboardType];
206    }
207}
208
209
210
211@end
Note: See TracBrowser for help on using the repository browser.