source: trunk/Cocoa/F-Script Anywhere/Source/NJRLabeledImageCell.m @ 221

Last change on this file since 221 was 19, checked in by Nicholas Riley, 17 years ago

F-Script Anywhere 1.1.6d1

File size: 7.4 KB
Line 
1//
2//  NJRLabeledImageCell.m
3//  HostLauncher
4//
5//  Created by nicholas on Wed Aug 01 2001.
6//  Copyright (c) 2001 Nicholas Riley. All rights reserved.
7//
8
9/*
10
11 F-Script Anywhere is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 F-Script Anywhere is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with F-Script Anywhere; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25*/
26
27#import "NJRLabeledImageCell.h"
28#import "NSString-NJRExtensions.h"
29
30const static float LEFT_PADDING = 3;
31
32@implementation NJRLabeledImageCell
33
34+ (NJRLabeledImageCell *)cell {
35    return [[[self alloc] init] autorelease];
36}
37
38- (void)dealloc {
39    [image release];
40    [imageCacheSource release];
41    image = nil;
42    [super dealloc];
43}
44
45- copyWithZone:(NSZone *)zone {
46    NJRLabeledImageCell *cell = [super copyWithZone:zone];
47    cell->image = [image retain];
48    return cell;
49}
50
51- (void)setImage:(NSImage *)anImage {
52    if (anImage != image) {
53        [image release];
54        image = [anImage retain];
55    }
56}
57
58- (NSImage *)image {
59    return image;
60}
61
62- (void)setImageCacheSource:(id)aSource {
63    if (aSource != imageCacheSource) {
64        [imageCacheSource release];
65        imageCacheSource = [aSource retain];
66    }
67}
68
69- (NSRect)imageFrameForCellFrame:(NSRect)cellFrame {
70    if (image != nil) {
71        NSRect imageFrame;
72        imageFrame.size = [image size];
73        imageFrame.origin = cellFrame.origin;
74        imageFrame.origin.x += LEFT_PADDING;
75        imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
76        return imageFrame;
77    }
78    return NSZeroRect;
79}
80
81- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
82    NSRect textFrame, imageFrame;
83    NSDivideRect(aRect, &imageFrame, &textFrame,
84                 LEFT_PADDING + [image size].width, NSMinXEdge);
85    [super editWithFrame: textFrame inView: controlView
86           editor: textObj delegate: anObject event: theEvent];
87}
88
89- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength {
90    NSRect textFrame, imageFrame;
91    NSDivideRect(aRect, &imageFrame, &textFrame, LEFT_PADDING + [image size].width,
92                 NSMinXEdge);
93    [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength];
94}
95
96- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
97    if (image != nil) {
98        NSSize  imageSize;
99        NSRect  imageFrame;
100        NSImageRep *preferredRep, *rep;
101
102        imageSize = NSMakeSize(cellFrame.size.height - 1, cellFrame.size.height - 1);
103
104        preferredRep = [[[imageCacheSource cachedImage] representations] objectAtIndex: 0];
105        if (preferredRep != nil && abs([preferredRep size].width - imageSize.width) < 1 && abs([preferredRep size].height != imageSize.height) < 1) {
106            [self setImage: [imageCacheSource cachedImage]];
107            // FSALog(@"%@ accepting cached image: %@", [self stringValue], preferredRep);
108        } else {
109            NSArray     *imageReps = [image representations];
110            int         i, repCount = [imageReps count];
111            NSSize      repSize;
112           
113            preferredRep = [imageReps objectAtIndex: 0];
114            // FSALog(@"%@ rejecting cached image: %@", [self stringValue], preferredRep);
115            for (i = 1 ; i < repCount ; i++) {
116                rep = [imageReps objectAtIndex: i];
117                repSize = [rep size];
118                if (repSize.width == imageSize.width && repSize.height == imageSize.height) {
119                    preferredRep = rep;
120                    break;
121                }
122                if (repSize.width >= imageSize.width || repSize.height >= imageSize.height) {
123                    // pick the smallest of the larger representations
124                    if (repSize.width <= [preferredRep size].width ||
125                        repSize.height <= [preferredRep size].height) preferredRep = rep;
126                } else {
127                    // or the largest of the smaller representations
128                    if (repSize.width >= [preferredRep size].width ||
129                        repSize.height >= [preferredRep size].height) preferredRep = rep;
130                }
131            }
132            /* // Working code as of OS X 10.0.4; this breaks in 10.1
133                for (i = repCount - 1 ; i >= 0 ; i--) {
134                    rep = [imageReps objectAtIndex: i];
135                    if (rep != preferredRep) {
136                        [image removeRepresentation: rep];
137                    }
138                }
139            // End working code
140            */
141            // Begin workaround code for bug in OS X 10.1 (removeRepresentation: has no effect)
142            if ([preferredRep size].width > imageSize.width || [preferredRep size].height > imageSize.height) {
143                NSImage *scaledImage = [[NSImage alloc] initWithSize: imageSize];
144                NSRect rect = { NSZeroPoint, imageSize };
145                FSALog(@"rescaling %@", [self stringValue]);
146                [scaledImage setFlipped: [controlView isFlipped]]; // XXX this works, but is correct?
147                [scaledImage lockFocus];
148                [preferredRep drawInRect: rect];
149                [scaledImage unlockFocus];
150                [image release];
151                image = scaledImage;
152            } else if (repCount > 1) {
153                NSImage *sizedImage = [[NSImage alloc] initWithSize: [preferredRep size]];
154                [sizedImage addRepresentation: preferredRep];
155                [image release];
156                image = sizedImage;
157            }
158            // End workaround code
159        }
160       
161        NSDivideRect(cellFrame, &imageFrame, &cellFrame,
162                     LEFT_PADDING + imageSize.width, NSMinXEdge);
163        if ([self drawsBackground]) {
164            [[self backgroundColor] set];
165            NSRectFill(imageFrame);
166        }
167        imageFrame.origin.x += LEFT_PADDING;
168        imageFrame.size = imageSize;
169
170        imageFrame.origin.y += ceil((cellFrame.size.height +
171                                     ([controlView isFlipped] ? -1 : 1) *
172                                        imageFrame.size.height - 2) / 2);
173        if ([image isFlipped] != [controlView isFlipped])
174            [image setFlipped: [controlView isFlipped]];
175        [image drawInRect: imageFrame
176            fromRect: NSOffsetRect(imageFrame, -imageFrame.origin.x, -imageFrame.origin.y)
177            operation: NSCompositeSourceOver fraction: 1.0];
178        [imageCacheSource setCachedImage: image];
179    }
180    [self setAttributedStringValue:
181        [[self stringValue] asAttributedStringTruncatedToWidth: cellFrame.size.width - 4]];
182    [self setImageCacheSource: nil]; // without this, we crash (multiple cells get created!)
183    [super drawWithFrame: cellFrame inView: controlView];
184}
185
186- (NSSize)cellSize {
187    NSSize cellSize = [super cellSize];
188    cellSize.width += (image ? [image size].width : 0) + LEFT_PADDING;
189    return cellSize;
190}
191
192@end
Note: See TracBrowser for help on using the repository browser.