]> git.sesse.net Git - vlc/blob - projects/macosx/vlc_app/Sources/ImageAndTextCell.m
Rework of vout_OSDEpg.
[vlc] / projects / macosx / vlc_app / Sources / ImageAndTextCell.m
1 /*****************************************************************************
2  * ImageAndTextCell.h: Helpful cell to display an image and a text.
3  * Borrowed from Apple's sample code for most part.
4  *****************************************************************************
5  * Copyright (C) 2007 Pierre d'Herbemont
6  * Copyright (C) 2007 the VideoLAN team
7  * $Id$
8  *
9  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
10  *
11  * This program 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  * This program 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 this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #import "ImageAndTextCell.h"
27
28 @implementation ImageAndTextCell
29
30 @synthesize imageKeyPath;
31 @synthesize representedObject;
32
33 - (id)init {
34     if (self = [super init]) {
35         [self setLineBreakMode:NSLineBreakByTruncatingTail];
36         [self setSelectable:YES];
37     }
38     return self;
39 }
40
41 - (void)dealloc {
42     [imageKeyPath release];
43     [super dealloc];
44 }
45
46 - (id)copyWithZone:(NSZone *)zone {
47     ImageAndTextCell *cell = (ImageAndTextCell *)[super copyWithZone:zone];
48     cell->imageKeyPath = [imageKeyPath copy];
49     cell->representedObject = [representedObject retain];
50     return cell;
51 }
52
53 - (NSImage *)cellImage
54 {
55     return imageKeyPath ? [[self representedObject] valueForKeyPath: imageKeyPath] : nil;
56 }
57
58 - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
59     NSRect textFrame, imageFrame;
60     NSImage * image = [self cellImage];
61     NSDivideRect (aRect, &imageFrame, &textFrame, 6 + [image size].width, NSMinXEdge);
62     [super editWithFrame: textFrame inView: controlView editor:textObj delegate:anObject event: theEvent];
63 }
64
65 - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength {
66     NSRect textFrame, imageFrame;
67     NSImage * image = [self cellImage];
68     NSDivideRect (aRect, &imageFrame, &textFrame, 6 + [image size].width, NSMinXEdge);
69     [super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength];
70 }
71
72 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
73     NSImage * image = [self cellImage];
74     if (image != nil) {
75         NSRect  imageFrame;
76         NSSize imageSize = [image size];
77         NSDivideRect(cellFrame, &imageFrame, &cellFrame, 6 + imageSize.width, NSMinXEdge);
78         if ([self drawsBackground]) {
79             [[self backgroundColor] set];
80             NSRectFill(imageFrame);
81         }
82         imageFrame.origin.x += 3;
83         imageFrame.size = imageSize;
84
85         if ([controlView isFlipped])
86             imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
87         else
88             imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
89
90         [image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
91     }
92     [super drawWithFrame:cellFrame inView:controlView];
93 }
94
95 - (NSSize)cellSize {
96     NSImage * image = [self cellImage];
97     NSSize cellSize = [super cellSize];
98     cellSize.width += (image ? [image size].width : 0) + 6;
99     return cellSize;
100 }
101
102 - (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
103     NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
104     NSImage * image = [self cellImage];
105     // If we have an image, we need to see if the user clicked on the image portion.
106     if (image != nil) {
107         // This code closely mimics drawWithFrame:inView:
108         NSSize imageSize = [image size];
109         NSRect imageFrame;
110         NSDivideRect(cellFrame, &imageFrame, &cellFrame, 6 + imageSize.width, NSMinXEdge);
111         
112         imageFrame.origin.x += 3;
113         imageFrame.size = imageSize;
114         // If the point is in the image rect, then it is a content hit
115         if (NSMouseInRect(point, imageFrame, [controlView isFlipped])) {
116             // We consider this just a content area. It is not trackable, nor it it editable text. If it was, we would or in the additional items.
117             // By returning the correct parts, we allow NSTableView to correctly begin an edit when the text portion is clicked on.
118             return NSCellHitContentArea;
119         }        
120     }
121     // At this point, the cellFrame has been modified to exclude the portion for the image. Let the superclass handle the hit testing at this point.
122     return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];    
123 }
124
125
126 @end