Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(454)

Side by Side Diff: chrome/browser/cocoa/download_shelf_controller.mm

Issue 165295: Add "dangerous download" view on OS X, for now for dmg files. Also fix download item layout. (Closed)
Patch Set: Address comments Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/cocoa/download_shelf_controller.h" 5 #import "chrome/browser/cocoa/download_shelf_controller.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/mac_util.h" 8 #include "base/mac_util.h"
9 #include "base/sys_string_conversions.h" 9 #include "base/sys_string_conversions.h"
10 #include "chrome/browser/browser.h" 10 #include "chrome/browser/browser.h"
11 #import "chrome/browser/cocoa/browser_window_controller.h" 11 #import "chrome/browser/cocoa/browser_window_controller.h"
12 #include "chrome/browser/cocoa/browser_window_cocoa.h" 12 #include "chrome/browser/cocoa/browser_window_cocoa.h"
13 #include "chrome/browser/cocoa/download_item_controller.h" 13 #include "chrome/browser/cocoa/download_item_controller.h"
14 #include "chrome/browser/cocoa/download_shelf_mac.h" 14 #include "chrome/browser/cocoa/download_shelf_mac.h"
15 #import "chrome/browser/cocoa/download_shelf_view.h" 15 #import "chrome/browser/cocoa/download_shelf_view.h"
16 #include "grit/generated_resources.h" 16 #include "grit/generated_resources.h"
17 17
18 namespace { 18 namespace {
19 19
20 // Max number of download views we'll contain. Any time a view is added and 20 // Max number of download views we'll contain. Any time a view is added and
21 // we already have this many download views, one is removed. 21 // we already have this many download views, one is removed.
22 const size_t kMaxDownloadItemCount = 16; 22 const size_t kMaxDownloadItemCount = 16;
23 23
24 // Border padding of a download item. 24 // Border padding of a download item.
25 const int kDownloadItemBorderPadding = 3; 25 const int kDownloadItemBorderPadding = 3;
26 26
27 // Width of a download item, must match width in DownloadItem.xib.
28 const int kDownloadItemWidth = 200;
29
30 // Height of a download item, must match height in DownloadItem.xib.
31 const int kDownloadItemHeight = 34;
32
33 // Horizontal padding between two download items. 27 // Horizontal padding between two download items.
34 const int kDownloadItemPadding = 10; 28 const int kDownloadItemPadding = 10;
35 29
36 // Duration for the open-new-leftmost-item animation, in seconds. 30 // Duration for the open-new-leftmost-item animation, in seconds.
37 const NSTimeInterval kDownloadItemOpenDuration = 0.8; 31 const NSTimeInterval kDownloadItemOpenDuration = 0.8;
38 32
39 } // namespace 33 } // namespace
40 34
41 @interface DownloadShelfController(Private) 35 @interface DownloadShelfController(Private)
42 - (void)applyContentAreaOffset:(BOOL)apply; 36 - (void)applyContentAreaOffset:(BOOL)apply;
43 - (void)showDownloadShelf:(BOOL)enable; 37 - (void)showDownloadShelf:(BOOL)enable;
44 - (void)resizeDownloadLinkToFit; 38 - (void)resizeDownloadLinkToFit;
39 - (void)layoutItems:(BOOL)skipFirst;
45 @end 40 @end
46 41
47 42
48 @implementation DownloadShelfController 43 @implementation DownloadShelfController
49 44
50 - (id)initWithBrowser:(Browser*)browser 45 - (id)initWithBrowser:(Browser*)browser
51 resizeDelegate:(id<ViewResizer>)resizeDelegate { 46 resizeDelegate:(id<ViewResizer>)resizeDelegate {
52 if ((self = [super initWithNibName:@"DownloadShelf" 47 if ((self = [super initWithNibName:@"DownloadShelf"
53 bundle:mac_util::MainAppBundle()])) { 48 bundle:mac_util::MainAppBundle()])) {
54 resizeDelegate_ = resizeDelegate; 49 resizeDelegate_ = resizeDelegate;
55 shelfHeight_ = [[self view] bounds].size.height; 50 shelfHeight_ = [[self view] bounds].size.height;
56 51
57 // Reset the download shelf's frame to zero. It will be properly positioned 52 // Reset the download shelf's frame to zero. It will be properly positioned
58 // and sized the first time we try to set its height. 53 // and sized the first time we try to set its height.
59 [[self view] setFrame:NSZeroRect]; 54 [[self view] setFrame:NSZeroRect];
60 55
61 downloadItemControllers_.reset([[NSMutableArray alloc] init]); 56 downloadItemControllers_.reset([[NSMutableArray alloc] init]);
62 57
63 // This calls show:, so it needs to be last. 58 // This calls show:, so it needs to be last.
64 bridge_.reset(new DownloadShelfMac(browser, self)); 59 bridge_.reset(new DownloadShelfMac(browser, self));
65 } 60 }
66 return self; 61 return self;
67 } 62 }
68 63
69 - (void)awakeFromNib { 64 - (void)awakeFromNib {
70 // Initialize "Show all downloads" link. 65 // Initialize "Show all downloads" link.
71 66
72 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( 67 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
73 [[NSParagraphStyle defaultParagraphStyle] mutableCopy]); 68 [[NSParagraphStyle defaultParagraphStyle] mutableCopy]);
74 // TODO(thakis): left-align for RTL languages?
75 [paragraphStyle.get() setAlignment:NSRightTextAlignment]; 69 [paragraphStyle.get() setAlignment:NSRightTextAlignment];
76 70
77 NSDictionary* linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 71 NSDictionary* linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
78 @"", NSLinkAttributeName, 72 @"", NSLinkAttributeName,
79 [NSCursor pointingHandCursor], NSCursorAttributeName, 73 [NSCursor pointingHandCursor], NSCursorAttributeName,
80 paragraphStyle.get(), NSParagraphStyleAttributeName, 74 paragraphStyle.get(), NSParagraphStyleAttributeName,
81 nil]; 75 nil];
82 NSString* text = 76 NSString* text =
83 base::SysWideToNSString(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS)); 77 base::SysWideToNSString(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS));
84 scoped_nsobject<NSAttributedString> linkText([[NSAttributedString alloc] 78 scoped_nsobject<NSAttributedString> linkText([[NSAttributedString alloc]
(...skipping 10 matching lines...) Expand all
95 in downloadItemControllers_.get()) { 89 in downloadItemControllers_.get()) {
96 [[NSNotificationCenter defaultCenter] removeObserver:itemController]; 90 [[NSNotificationCenter defaultCenter] removeObserver:itemController];
97 } 91 }
98 [super dealloc]; 92 [super dealloc];
99 } 93 }
100 94
101 - (void)resizeDownloadLinkToFit { 95 - (void)resizeDownloadLinkToFit {
102 // Get width required by localized download link text. 96 // Get width required by localized download link text.
103 // http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/Tasks/ StringHeight.html 97 // http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/Tasks/ StringHeight.html
104 [[showAllDownloadsLink_ textContainer] setLineFragmentPadding:0.0]; 98 [[showAllDownloadsLink_ textContainer] setLineFragmentPadding:0.0];
105 (void)[[showAllDownloadsLink_ layoutManager]glyphRangeForTextContainer: 99 (void)[[showAllDownloadsLink_ layoutManager] glyphRangeForTextContainer:
106 [showAllDownloadsLink_ textContainer]]; 100 [showAllDownloadsLink_ textContainer]];
107 NSRect textRect = [[showAllDownloadsLink_ layoutManager] 101 NSRect textRect = [[showAllDownloadsLink_ layoutManager]
108 usedRectForTextContainer:[showAllDownloadsLink_ textContainer]]; 102 usedRectForTextContainer:[showAllDownloadsLink_ textContainer]];
109 103
110 int offsetX = [showAllDownloadsLink_ frame].size.width - textRect.size.width; 104 int offsetX = [showAllDownloadsLink_ frame].size.width - textRect.size.width;
111 105
112 // Fit link itself. 106 // Fit link itself.
113 NSRect linkFrame = [linkContainer_ frame]; 107 NSRect linkFrame = [linkContainer_ frame];
114 linkFrame.origin.x += offsetX; 108 linkFrame.origin.x += offsetX;
115 linkFrame.size.width -= offsetX; 109 linkFrame.size.width -= offsetX;
(...skipping 22 matching lines...) Expand all
138 132
139 - (void)remove:(DownloadItemController*)download { 133 - (void)remove:(DownloadItemController*)download {
140 // Look for the download in our controller array and remove it. This will 134 // Look for the download in our controller array and remove it. This will
141 // explicity release it so that it removes itself as an Observer of the 135 // explicity release it so that it removes itself as an Observer of the
142 // DownloadItem. We don't want to wait for autorelease since the DownloadItem 136 // DownloadItem. We don't want to wait for autorelease since the DownloadItem
143 // we are observing will likely be gone by then. 137 // we are observing will likely be gone by then.
144 [[NSNotificationCenter defaultCenter] removeObserver:download]; 138 [[NSNotificationCenter defaultCenter] removeObserver:download];
145 [[download view] removeFromSuperview]; 139 [[download view] removeFromSuperview];
146 [downloadItemControllers_ removeObject:download]; 140 [downloadItemControllers_ removeObject:download];
147 141
148 // TODO(thakis): Need to relayout the remaining item views here ( 142 [self layoutItems];
149 // crbug.com/17831 ).
150 143
151 // Check to see if we have any downloads remaining and if not, hide the shelf. 144 // Check to see if we have any downloads remaining and if not, hide the shelf.
152 if (![downloadItemControllers_ count]) 145 if (![downloadItemControllers_ count])
153 [self showDownloadShelf:NO]; 146 [self showDownloadShelf:NO];
154 } 147 }
155 148
156 // We need to explicitly release our download controllers here since they need 149 // We need to explicitly release our download controllers here since they need
157 // to remove themselves as observers before the remaining shutdown happens. 150 // to remove themselves as observers before the remaining shutdown happens.
158 - (void)exiting { 151 - (void)exiting {
159 downloadItemControllers_.reset(); 152 downloadItemControllers_.reset();
(...skipping 29 matching lines...) Expand all
189 if (sender) 182 if (sender)
190 bridge_->Close(); 183 bridge_->Close();
191 else 184 else
192 [self showDownloadShelf:NO]; 185 [self showDownloadShelf:NO];
193 } 186 }
194 187
195 - (float)height { 188 - (float)height {
196 return shelfHeight_; 189 return shelfHeight_;
197 } 190 }
198 191
199 - (void)addDownloadItem:(BaseDownloadItemModel*)model { 192 // If |skipFirst| is true, the frame of the leftmost item is not set.
200 // TODO(thakis): RTL support? 193 - (void)layoutItems:(BOOL)skipFirst {
201 // (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) 194 CGFloat currentX = 0;
202 // Shift all existing items to the right
203 for (DownloadItemController* itemController 195 for (DownloadItemController* itemController
204 in downloadItemControllers_.get()) { 196 in downloadItemControllers_.get()) {
205 NSRect frame = [[itemController view] frame]; 197 NSRect frame = [[itemController view] frame];
206 frame.origin.x += kDownloadItemWidth + kDownloadItemPadding; 198 frame.origin.x = currentX;
207 [[[itemController view] animator] setFrame:frame]; 199 frame.size.width = [itemController preferredSize].width;
200 if (!skipFirst)
201 [[[itemController view] animator] setFrame:frame];
202 currentX += frame.size.width + kDownloadItemPadding;
203 skipFirst = NO;
208 } 204 }
205 }
209 206
207 - (void)layoutItems {
208 [self layoutItems:NO];
209 }
210
211 - (void)addDownloadItem:(BaseDownloadItemModel*)model {
210 // Insert new item at the left. 212 // Insert new item at the left.
211 // Start at width 0...
212 NSRect position = NSMakeRect(0, kDownloadItemBorderPadding,
213 0, kDownloadItemHeight);
214 scoped_nsobject<DownloadItemController> controller( 213 scoped_nsobject<DownloadItemController> controller(
215 [[DownloadItemController alloc] initWithFrame:position 214 [[DownloadItemController alloc] initWithModel:model shelf:self]);
216 model:model 215
217 shelf:self]); 216 // Adding at index 0 in NSMutableArrays is O(1).
218 [downloadItemControllers_ addObject:controller.get()]; 217 [downloadItemControllers_ insertObject:controller.get() atIndex:0];
219 218
220 [itemContainerView_ addSubview:[controller.get() view]]; 219 [itemContainerView_ addSubview:[controller.get() view]];
221 220
222 [[NSNotificationCenter defaultCenter] 221 [[NSNotificationCenter defaultCenter]
223 addObserver:controller 222 addObserver:controller
224 selector:@selector(updateVisibility:) 223 selector:@selector(updateVisibility:)
225 name:NSViewFrameDidChangeNotification 224 name:NSViewFrameDidChangeNotification
226 object:[controller view]]; 225 object:[controller view]];
227 [[NSNotificationCenter defaultCenter] 226 [[NSNotificationCenter defaultCenter]
228 addObserver:controller 227 addObserver:controller
229 selector:@selector(updateVisibility:) 228 selector:@selector(updateVisibility:)
230 name:NSViewFrameDidChangeNotification 229 name:NSViewFrameDidChangeNotification
231 object:itemContainerView_]; 230 object:itemContainerView_];
232 231
232 // Start at width 0...
233 NSSize size = [controller.get() preferredSize];
234 NSRect frame = NSMakeRect(0, kDownloadItemBorderPadding, 0, size.height);
235 [[controller.get() view] setFrame:frame];
236
233 // ...then animate in 237 // ...then animate in
234 NSRect frame = [[controller.get() view] frame]; 238 frame.size.width = size.width;
235 frame.size.width = kDownloadItemWidth;
236
237 [NSAnimationContext beginGrouping]; 239 [NSAnimationContext beginGrouping];
238 [[NSAnimationContext currentContext] setDuration:kDownloadItemOpenDuration]; 240 [[NSAnimationContext currentContext] setDuration:kDownloadItemOpenDuration];
239 [[[controller.get() view] animator] setFrame:frame]; 241 [[[controller.get() view] animator] setFrame:frame];
240 [NSAnimationContext endGrouping]; 242 [NSAnimationContext endGrouping];
241 243
242 // Keep only a limited number of items in the shelf. 244 // Keep only a limited number of items in the shelf.
243 if ([downloadItemControllers_ count] > kMaxDownloadItemCount) { 245 if ([downloadItemControllers_ count] > kMaxDownloadItemCount) {
244 DCHECK(kMaxDownloadItemCount > 0); 246 DCHECK(kMaxDownloadItemCount > 0);
245 247
246 // Since no user will ever see the item being removed (needs a horizontal 248 // Since no user will ever see the item being removed (needs a horizontal
247 // screen resolution greater than 3200 at 16 items at 200 pixels each), 249 // screen resolution greater than 3200 at 16 items at 200 pixels each),
248 // there's no point in animating the removal. 250 // there's no point in animating the removal.
249 [self remove:[downloadItemControllers_ objectAtIndex:0]]; 251 [self remove:[downloadItemControllers_ lastObject]];
250 } 252 }
253
254 // Finally, move the remaining items to the right. Skip the first item when
255 // laying out the items, so that the longer animation duration we set up above
256 // is not overwritten.
257 [self layoutItems:YES];
251 } 258 }
252 259
253 @end 260 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/download_shelf_controller.h ('k') | chrome/browser/download/download_exe.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698