1/*
2   Grr RSS Reader
3
4   Copyright (C) 2006, 2007 Guenther Noack <guenther@unix-ag.uni-kl.de>
5   Copyright (C) 2009  GNUstep Application Team
6                       Riccardo Mottola
7
8   This application is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public
10   License as published by the Free Software Foundation; either
11   version 3 of the License, or (at your option) any later version.
12
13   This application is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Library General Public License for more details.
17
18   You should have received a copy of the GNU General Public
19   License along with this library; if not, write to the Free
20   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21*/
22
23#import "GNRatingCell.h"
24
25#ifdef __APPLE__
26#import "GNUstep.h"
27#endif
28
29/**
30 * This cell shows a rating displayed as 0 to 5 horizontally aligned stars. You can
31 * modify the rating by clicking the desired position of the rightmost star. A click
32 * left or right beyond the borders of the rectangle that would surround five stars
33 * sets the number of stars to the maximum 5 or the minimum 0.
34 *
35 * Revision History
36 *   Nov 20 2006 - Initial version
37 *
38 * FIXME: Why does NSTableView open a *text editing field* when you double click on this
39 *        view in a table?!?
40 */
41@implementation GNRatingCell
42
43// ----------------------------------------------------------------
44//    initializers
45// ----------------------------------------------------------------
46
47-(id) initTextCell: (NSString*) text
48{
49    return [self initImageCell: [NSImage imageNamed: @"Star"]];
50}
51
52-(id) initImageCell: (NSImage*) image
53{
54    if ((self = [super initImageCell: image]) != nil) {
55        ASSIGN(star, image);
56    }
57
58    return self;
59}
60
61// ----------------------------------------------------------------
62//    mouse tracking
63// ----------------------------------------------------------------
64
65-(BOOL) trackMouse: (NSEvent*) theEvent
66            inRect: (NSRect) cellFrame
67            ofView: (NSView*) controlView
68      untilMouseUp: (BOOL) flag
69{
70    // Just remember the rect of the cell, then go on with tracking
71    // and wait for the call to stopTracking:at:inView:mouseIsUp:
72    _currentTrackingRect = cellFrame;
73
74    return [super trackMouse: theEvent
75                      inRect: cellFrame
76                      ofView: controlView
77                untilMouseUp: flag];
78}
79
80- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
81{
82    return YES;
83}
84
85-(void) stopTracking: (NSPoint)lastPoint
86                  at: (NSPoint)stopPoint
87              inView: (NSView*)aView
88           mouseIsUp: (BOOL)isUpFlag
89{
90    if (isUpFlag) {
91        NSSize size = [star size];
92
93        // The field _currentTrackingRect is set by the trackMouse:inRect:ofView:untilMouseUp:
94        // method before it calls the stopTracking:at:inView:mouseIsUp: (this) method. At the
95        // moment I just trust nobody will call stopTracking:... manually.
96        float leftestStarX = NSMidX(_currentTrackingRect) - size.width * 2.5;
97        float rightestStarX = leftestStarX + size.width * 5.0;
98
99        if (stopPoint.x <= leftestStarX) {
100            [self setIntValue: 0];
101        } else if (stopPoint.x <= rightestStarX) {
102            float res = ((stopPoint.x - leftestStarX) / size.width) + 1.0;
103            [self setFloatValue: res];
104        } else {
105            [self setIntValue: 5];
106        }
107    }
108}
109
110
111// ----------------------------------------------------------------
112//    GNUstep workaround for buggy NSTableView behaviour
113// ----------------------------------------------------------------
114#ifdef GNUSTEP
115/*
116 * According to Matt Rice, switching off editability for a cell
117 * lets the mouse tracking still work. As long as the table column
118 * is still editable, updating changed table cells works, too.
119 * This is undefined behaviour, though, and may not work in future
120 * releases of GNUstep.
121 *
122 * This doesn't work for me on GNUstep stable in Nov 2006. It's
123 * probably different for the SVN version.
124 */
125-(BOOL) isEditable {
126    return NO;
127}
128#endif
129
130// ----------------------------------------------------------------
131//    drawing
132// ----------------------------------------------------------------
133
134-(void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
135{
136    NSSize size;
137    NSPoint position;
138    int i;
139    int num;
140
141    if (star == nil) {
142        // init didn't take place, let's do something about it fast!
143        ASSIGN(star, [NSImage imageNamed: @"Star"]);
144    }
145
146    size = [star size];
147
148    position.x = MAX(NSMidX(cellFrame) - (size.width * 2.5),  0.0);
149    position.y = MAX(NSMidY(cellFrame) - (size.height / 2.0), 0.0);
150
151    if ([controlView isFlipped]) {
152        position.y += size.height;
153    }
154
155    num = [self intValue];
156
157    for (i=0; i<num; i++) {
158        [star compositeToPoint: position
159                     operation: NSCompositeSourceOver];
160
161        position.x += size.width;
162    }
163
164    for (;i<5;i++) {
165        [star dissolveToPoint: position
166                     fraction: 0.2];
167
168        position.x += size.width;
169    }
170}
171
172@end
173
174