1/******************************************************************************
2 * Copyright (c) 2007-2012 Transmission authors and contributors
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
22
23#import "FilePriorityCell.h"
24#import "FileOutlineView.h"
25#import "FileListNode.h"
26#import "NSImageAdditions.h"
27#import "Torrent.h"
28
29#define IMAGE_OVERLAP 1.0
30
31@implementation FilePriorityCell
32
33- (id) init
34{
35    if ((self = [super init]))
36    {
37        [self setTrackingMode: NSSegmentSwitchTrackingSelectAny];
38        [self setControlSize: NSMiniControlSize];
39        [self setSegmentCount: 3];
40
41        for (NSInteger i = 0; i < [self segmentCount]; i++)
42        {
43            [self setLabel: @"" forSegment: i];
44            [self setWidth: 9.0f forSegment: i]; //9 is minimum size to get proper look
45        }
46
47        [self setImage: [NSImage imageNamed: @"PriorityControlLow"] forSegment: 0];
48        [self setImage: [NSImage imageNamed: @"PriorityControlNormal"] forSegment: 1];
49        [self setImage: [NSImage imageNamed: @"PriorityControlHigh"] forSegment: 2];
50
51        fHoverRow = NO;
52    }
53    return self;
54}
55
56- (id) copyWithZone: (NSZone *) zone
57{
58    id value = [super copyWithZone: zone];
59    [value setRepresentedObject: [self representedObject]];
60    return value;
61}
62
63- (void) setSelected: (BOOL) flag forSegment: (NSInteger) segment
64{
65    [super setSelected: flag forSegment: segment];
66
67    //only for when clicking manually
68    NSInteger priority;
69    switch (segment)
70    {
71        case 0:
72            priority = TR_PRI_LOW;
73            break;
74        case 1:
75            priority = TR_PRI_NORMAL;
76            break;
77        case 2:
78            priority = TR_PRI_HIGH;
79            break;
80    }
81
82    Torrent * torrent = [(FileListNode *)[self representedObject] torrent];
83    [torrent setFilePriority: priority forIndexes: [(FileListNode *)[self representedObject] indexes]];
84
85    FileOutlineView * controlView = (FileOutlineView *)[self controlView];
86    [controlView setNeedsDisplay: YES];
87}
88
89- (void) addTrackingAreasForView: (NSView *) controlView inRect: (NSRect) cellFrame withUserInfo: (NSDictionary *) userInfo
90            mouseLocation: (NSPoint) mouseLocation
91{
92    NSTrackingAreaOptions options = NSTrackingEnabledDuringMouseDrag | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways;
93
94    if (NSMouseInRect(mouseLocation, cellFrame, [controlView isFlipped]))
95    {
96        options |= NSTrackingAssumeInside;
97        [controlView setNeedsDisplayInRect: cellFrame];
98    }
99
100    NSTrackingArea * area = [[NSTrackingArea alloc] initWithRect: cellFrame options: options owner: controlView userInfo: userInfo];
101    [controlView addTrackingArea: area];
102}
103
104- (void) setHovered: (BOOL) hovered
105{
106    fHoverRow = hovered;
107}
108
109- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) controlView
110{
111    FileListNode * node = [self representedObject];
112    Torrent * torrent = [node torrent];
113    NSSet * priorities = [torrent filePrioritiesForIndexes: [node indexes]];
114
115    const NSUInteger count = [priorities count];
116    if (fHoverRow && count > 0)
117    {
118        [super setSelected: [priorities containsObject: @(TR_PRI_LOW)] forSegment: 0];
119        [super setSelected: [priorities containsObject: @(TR_PRI_NORMAL)] forSegment: 1];
120        [super setSelected: [priorities containsObject: @(TR_PRI_HIGH)] forSegment: 2];
121
122        [super drawWithFrame: cellFrame inView: controlView];
123    }
124    else
125    {
126        NSMutableArray * images = [NSMutableArray arrayWithCapacity: MAX(count, 1u)];
127        CGFloat totalWidth;
128
129        if (count == 0)
130        {
131            //if ([self backgroundStyle] != NSBackgroundStyleDark)
132            {
133                NSImage * image = [[NSImage imageNamed: @"PriorityNormalTemplate"] imageWithColor: [NSColor lightGrayColor]];
134                [images addObject: image];
135                totalWidth = [image size].width;
136            }
137        }
138        else
139        {
140            NSColor * priorityColor = [self backgroundStyle] == NSBackgroundStyleDark ? [NSColor whiteColor] : [NSColor darkGrayColor];
141
142            totalWidth = 0.0;
143            if ([priorities containsObject: @(TR_PRI_LOW)])
144            {
145                NSImage * image = [[NSImage imageNamed: @"PriorityLowTemplate"] imageWithColor: priorityColor];
146                [images addObject: image];
147                totalWidth += [image size].width;
148            }
149            if ([priorities containsObject: @(TR_PRI_NORMAL)])
150            {
151                NSImage * image = [[NSImage imageNamed: @"PriorityNormalTemplate"] imageWithColor: priorityColor];
152                [images addObject: image];
153                totalWidth += [image size].width;
154            }
155            if ([priorities containsObject: @(TR_PRI_HIGH)])
156            {
157                NSImage * image = [[NSImage imageNamed: @"PriorityHighTemplate"] imageWithColor: priorityColor];
158                [images addObject: image];
159                totalWidth += [image size].width;
160            }
161        }
162
163        if (count > 1)
164            totalWidth -= IMAGE_OVERLAP * (count-1);
165
166        CGFloat currentWidth = floor(NSMidX(cellFrame) - totalWidth * 0.5);
167
168        for (NSImage * image in images)
169        {
170            const NSSize imageSize = [image size];
171            const NSRect imageRect = NSMakeRect(currentWidth, floor(NSMidY(cellFrame) - imageSize.height * 0.5), imageSize.width, imageSize.height);
172
173            [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil];
174
175            currentWidth += imageSize.width - IMAGE_OVERLAP;
176        }
177    }
178}
179
180@end
181