OLD | NEW |
| (Empty) |
1 /* | |
2 File: ImageAndTextCell.m | |
3 Abstract: Subclass of NSTextFieldCell which can display text and an image simul
taneously. | |
4 Version: 1.0 | |
5 | |
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |
7 Inc. ("Apple") in consideration of your agreement to the following | |
8 terms, and your use, installation, modification or redistribution of | |
9 this Apple software constitutes acceptance of these terms. If you do | |
10 not agree with these terms, please do not use, install, modify or | |
11 redistribute this Apple software. | |
12 | |
13 In consideration of your agreement to abide by the following terms, and | |
14 subject to these terms, Apple grants you a personal, non-exclusive | |
15 license, under Apple's copyrights in this original Apple software (the | |
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple | |
17 Software, with or without modifications, in source and/or binary forms; | |
18 provided that if you redistribute the Apple Software in its entirety and | |
19 without modifications, you must retain this notice and the following | |
20 text and disclaimers in all such redistributions of the Apple Software. | |
21 Neither the name, trademarks, service marks or logos of Apple Inc. may | |
22 be used to endorse or promote products derived from the Apple Software | |
23 without specific prior written permission from Apple. Except as | |
24 expressly stated in this notice, no other rights or licenses, express or | |
25 implied, are granted by Apple herein, including but not limited to any | |
26 patent rights that may be infringed by your derivative works or by other | |
27 works in which the Apple Software may be incorporated. | |
28 | |
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |
34 | |
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |
42 POSSIBILITY OF SUCH DAMAGE. | |
43 | |
44 Copyright (C) 2009 Apple Inc. All Rights Reserved. | |
45 | |
46 */ | |
47 | |
48 #import "ImageAndTextCell.h" | |
49 #import <AppKit/NSCell.h> | |
50 | |
51 #if !defined(MAC_OS_X_VERSION_10_10) || \ | |
52 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10 | |
53 typedef NSUInteger NSCellHitResult; | |
54 #endif | |
55 | |
56 @implementation ImageAndTextCell | |
57 | |
58 @synthesize image; | |
59 | |
60 - (id)init { | |
61 if ((self = [super init])) { | |
62 [self setLineBreakMode:NSLineBreakByTruncatingTail]; | |
63 [self setSelectable:YES]; | |
64 } | |
65 return self; | |
66 } | |
67 | |
68 - (void)dealloc { | |
69 [image release]; | |
70 [super dealloc]; | |
71 } | |
72 | |
73 - (id)copyWithZone:(NSZone *)zone { | |
74 ImageAndTextCell *cell = (ImageAndTextCell *)[super copyWithZone:zone]; | |
75 // The image ivar will be directly copied; we need to retain or copy it. | |
76 cell->image = [image retain]; | |
77 return cell; | |
78 } | |
79 | |
80 - (NSRect)imageRectForBounds:(NSRect)cellFrame { | |
81 NSRect result; | |
82 if (image != nil) { | |
83 result.size = [image size]; | |
84 result.origin = cellFrame.origin; | |
85 result.origin.x += 3; | |
86 result.origin.y += ceil((cellFrame.size.height - result.size.height) / 2); | |
87 } else { | |
88 result = NSZeroRect; | |
89 } | |
90 return result; | |
91 } | |
92 | |
93 // We could manually implement expansionFrameWithFrame:inView: and drawWithExpan
sionFrame:inView: or just properly implement titleRectForBounds to get expansion
tooltips to automatically work for us | |
94 - (NSRect)titleRectForBounds:(NSRect)cellFrame { | |
95 NSRect result; | |
96 if (image != nil) { | |
97 CGFloat imageWidth = [image size].width; | |
98 result = cellFrame; | |
99 result.origin.x += (3 + imageWidth); | |
100 result.size.width -= (3 + imageWidth); | |
101 } else { | |
102 result = [super titleRectForBounds:cellFrame]; | |
103 } | |
104 return result; | |
105 } | |
106 | |
107 - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText
*)textObj delegate:(id)anObject event:(NSEvent *)theEvent { | |
108 NSRect textFrame, imageFrame; | |
109 NSDivideRect (aRect, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEd
ge); | |
110 [super editWithFrame: textFrame inView: controlView editor:textObj delegate:an
Object event: theEvent]; | |
111 } | |
112 | |
113 - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSTex
t *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)se
lLength { | |
114 NSRect textFrame, imageFrame; | |
115 NSDivideRect (aRect, &imageFrame, &textFrame, 3 + [image size].width, NSMinXEd
ge); | |
116 [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:
anObject start:selStart length:selLength]; | |
117 } | |
118 | |
119 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { | |
120 if (image != nil) { | |
121 NSRect imageFrame; | |
122 NSSize imageSize = [image size]; | |
123 NSDivideRect(cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMinX
Edge); | |
124 if ([self drawsBackground]) { | |
125 [[self backgroundColor] set]; | |
126 NSRectFill(imageFrame); | |
127 } | |
128 imageFrame.origin.x += 3; | |
129 imageFrame.origin.y += ceil((cellFrame.size.height - imageSize.height) / 2); | |
130 imageFrame.size = imageSize; | |
131 | |
132 [image drawInRect:imageFrame | |
133 fromRect:NSZeroRect | |
134 operation:NSCompositeSourceOver | |
135 fraction:1.0 | |
136 respectFlipped:YES | |
137 hints:nil]; | |
138 } | |
139 [super drawWithFrame:cellFrame inView:controlView]; | |
140 } | |
141 | |
142 - (NSSize)cellSize { | |
143 NSSize cellSize = [super cellSize]; | |
144 if (image != nil) { | |
145 cellSize.width += [image size].width; | |
146 } | |
147 cellSize.width += 3; | |
148 return cellSize; | |
149 } | |
150 | |
151 - (NSCellHitResult)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofV
iew:(NSView *)controlView { | |
152 NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:ni
l]; | |
153 // If we have an image, we need to see if the user clicked on the image portio
n. | |
154 if (image != nil) { | |
155 // This code closely mimics drawWithFrame:inView: | |
156 NSSize imageSize = [image size]; | |
157 NSRect imageFrame; | |
158 NSDivideRect(cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMinX
Edge); | |
159 | |
160 imageFrame.origin.x += 3; | |
161 imageFrame.size = imageSize; | |
162 // If the point is in the image rect, then it is a content hit | |
163 if (NSMouseInRect(point, imageFrame, [controlView isFlipped])) { | |
164 // We consider this just a content area. It is not trackable, nor it it ed
itable text. If it was, we would or in the additional items. | |
165 // By returning the correct parts, we allow NSTableView to correctly begin
an edit when the text portion is clicked on. | |
166 return NSCellHitContentArea; | |
167 } | |
168 } | |
169 // At this point, the cellFrame has been modified to exclude the portion for t
he image. Let the superclass handle the hit testing at this point. | |
170 return [super hitTestForEvent:event inRect:cellFrame ofView:controlView]; | |
171 } | |
172 | |
173 | |
174 @end | |
175 | |
OLD | NEW |