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

Last change on this file since 14 was 14, checked in by Nicholas Riley, 20 years ago

F-Script Anywhere 1.1.2

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.