summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/DownloadShelf.xib127
-rw-r--r--chrome/browser/cocoa/download_item_controller.h4
-rw-r--r--chrome/browser/cocoa/download_item_controller.mm13
-rw-r--r--chrome/browser/cocoa/download_shelf_controller.h25
-rw-r--r--chrome/browser/cocoa/download_shelf_controller.mm82
-rw-r--r--chrome/chrome.gyp1
6 files changed, 232 insertions, 20 deletions
diff --git a/chrome/app/nibs/DownloadShelf.xib b/chrome/app/nibs/DownloadShelf.xib
index f38954e..a910eab 100644
--- a/chrome/app/nibs/DownloadShelf.xib
+++ b/chrome/app/nibs/DownloadShelf.xib
@@ -84,7 +84,7 @@
<object class="NSTextView" id="550190606">
<reference key="NSNextResponder" ref="581923208"/>
<int key="NSvFlags">2322</int>
- <string key="NSFrameSize">{182, 31}</string>
+ <string key="NSFrameSize">{182, 12}</string>
<reference key="NSSuperview" ref="581923208"/>
<object class="NSTextContainer" key="NSTextContainer" id="526453298">
<object class="NSLayoutManager" key="NSLayoutManager">
@@ -280,7 +280,7 @@
</object>
<int key="NSTVFlags">6</int>
<string key="NSMaxSize">{463, 1e+07}</string>
- <string key="NSMinize">{63, 31}</string>
+ <string key="NSMinize">{63, 3}</string>
<nil key="NSDelegate"/>
</object>
</object>
@@ -300,7 +300,6 @@
<int key="NSvFlags">256</int>
<string key="NSFrame">{{-100, -100}, {15, 12}}</string>
<reference key="NSSuperview" ref="433009119"/>
- <bool key="NSEnabled">YES</bool>
<reference key="NSTarget" ref="433009119"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">1.369863e-02</double>
@@ -320,11 +319,50 @@
<string key="NSFrame">{{266, 13}, {182, 14}}</string>
<reference key="NSSuperview" ref="1005"/>
<reference key="NSNextKeyView" ref="581923208"/>
- <int key="NSsFlags">64</int>
+ <int key="NSsFlags">0</int>
<reference key="NSVScroller" ref="888760421"/>
<reference key="NSHScroller" ref="199551096"/>
<reference key="NSContentView" ref="581923208"/>
</object>
+ <object class="NSCustomView" id="931787328">
+ <reference key="NSNextResponder" ref="1005"/>
+ <int key="NSvFlags">290</int>
+ <string key="NSFrame">{{3, 0}, {240, 40}}</string>
+ <reference key="NSSuperview" ref="1005"/>
+ <string key="NSClassName">NSView</string>
+ </object>
+ <object class="NSImageView" id="663605208">
+ <reference key="NSNextResponder" ref="1005"/>
+ <int key="NSvFlags">289</int>
+ <object class="NSMutableSet" key="NSDragTypes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="set.sortedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Apple PDF pasteboard type</string>
+ <string>Apple PICT pasteboard type</string>
+ <string>Apple PNG pasteboard type</string>
+ <string>NSFilenamesPboardType</string>
+ <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
+ <string>NeXT TIFF v4.0 pasteboard type</string>
+ </object>
+ </object>
+ <string key="NSFrame">{{245, 11}, {16, 16}}</string>
+ <reference key="NSSuperview" ref="1005"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSImageCell" key="NSCell" id="673439633">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">33554432</int>
+ <object class="NSCustomResource" key="NSContents">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">downloads_favicon</string>
+ </object>
+ <int key="NSAlign">0</int>
+ <int key="NSScale">0</int>
+ <int key="NSStyle">0</int>
+ <bool key="NSAnimates">NO</bool>
+ </object>
+ <bool key="NSEditable">YES</bool>
+ </object>
</object>
<string key="NSFrameSize">{480, 40}</string>
<reference key="NSSuperview"/>
@@ -358,6 +396,30 @@
</object>
<int key="connectionID">15</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">linkContainer_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="433009119"/>
+ </object>
+ <int key="connectionID">18</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">itemContainerView_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="931787328"/>
+ </object>
+ <int key="connectionID">19</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">image_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="663605208"/>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -395,6 +457,8 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="538957441"/>
<reference ref="433009119"/>
+ <reference ref="931787328"/>
+ <reference ref="663605208"/>
</object>
<reference key="parent" ref="1002"/>
</object>
@@ -438,6 +502,25 @@
<reference key="object" ref="550190606"/>
<reference key="parent" ref="433009119"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">16</int>
+ <reference key="object" ref="931787328"/>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">20</int>
+ <reference key="object" ref="663605208"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="673439633"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">21</int>
+ <reference key="object" ref="673439633"/>
+ <reference key="parent" ref="663605208"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -455,6 +538,9 @@
<string>11.IBPluginDependency</string>
<string>12.IBPluginDependency</string>
<string>13.IBPluginDependency</string>
+ <string>16.IBPluginDependency</string>
+ <string>20.IBPluginDependency</string>
+ <string>21.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>4.IBPluginDependency</string>
</object>
@@ -463,7 +549,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{79, 87}, {480, 40}}</string>
+ <string>{{845, 30}, {480, 40}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{628, 654}</string>
<string>{{357, 416}, {480, 272}}</string>
@@ -473,6 +559,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -495,7 +584,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">15</int>
+ <int key="maxID">22</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -517,8 +606,21 @@
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">showAllDownloadsLink_</string>
- <string key="NS.object.0">NSTextView</string>
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>image_</string>
+ <string>itemContainerView_</string>
+ <string>linkContainer_</string>
+ <string>showAllDownloadsLink_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSImageView</string>
+ <string>NSView</string>
+ <string>NSScrollView</string>
+ <string>NSTextView</string>
+ </object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
@@ -537,13 +639,20 @@
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/status_bubble_mac.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
<string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
- <string key="IBDocument.LastKnownRelativeProjectPath">../../../chrome.xcodeproj</string>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../../chrome.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>
diff --git a/chrome/browser/cocoa/download_item_controller.h b/chrome/browser/cocoa/download_item_controller.h
index 8fa3831..7dc5e7e 100644
--- a/chrome/browser/cocoa/download_item_controller.h
+++ b/chrome/browser/cocoa/download_item_controller.h
@@ -42,6 +42,10 @@ class DownloadShelfContextMenuMac;
// Remove ourself from the download UI.
- (void)remove;
+// Update item's visibility depending on if the item is still completely
+// contained in its parent.
+- (void)updateVisibility:(id)sender;
+
// Asynchronous icon loading callback.
- (void)setIcon:(NSImage*)icon;
diff --git a/chrome/browser/cocoa/download_item_controller.mm b/chrome/browser/cocoa/download_item_controller.mm
index d00fd58..52ac1a1 100644
--- a/chrome/browser/cocoa/download_item_controller.mm
+++ b/chrome/browser/cocoa/download_item_controller.mm
@@ -29,6 +29,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
using DownloadShelfContextMenu::CANCEL;
};
+
// Implementation of DownloadItemController
@implementation DownloadItemController
@@ -55,9 +56,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
}
- (void)setStateFromDownload:(BaseDownloadItemModel*)downloadModel {
- // TODO(thakis): The windows version of this does all kinds of things
- // (gratituous use of animation, special handling of dangerous downloads)
- // that we don't currently do.
+ // TODO(thakis): handling of dangerous downloads -- crbug.com/14667
// Set the correct popup menu.
if (downloadModel->download()->state() == DownloadItem::COMPLETE)
@@ -78,6 +77,14 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu {
[shelf_ remove:self];
}
+- (void)updateVisibility:(id)sender {
+ // TODO(thakis): Make this prettier, by fading the items out or overlaying
+ // the partial visible one with a horizontal alpha gradient -- crbug.com/17830
+ NSView* view = [self view];
+ NSRect containerFrame = [[view superview] frame];
+ [view setHidden:(NSMaxX([view frame]) > NSWidth(containerFrame))];
+}
+
- (IBAction)handleButtonClick:(id)sender {
if ([cell_ isButtonPartPressed]) {
DownloadItem* download = bridge_->download_model()->download();
diff --git a/chrome/browser/cocoa/download_shelf_controller.h b/chrome/browser/cocoa/download_shelf_controller.h
index f598d5c..c72538a 100644
--- a/chrome/browser/cocoa/download_shelf_controller.h
+++ b/chrome/browser/cocoa/download_shelf_controller.h
@@ -14,12 +14,30 @@ class Browser;
class DownloadShelf;
@class DownloadShelfView;
-// A controller class that manages the download shelf for one window.
+// A controller class that manages the download shelf for one window. It is
+// responsible for the behavior of the shelf itself (showing/hiding, handling
+// the link, layout) as well as for managing the download items it contains.
+//
+// All the files in cocoa/downloads_* are related as follows:
+//
+// download_shelf_mac bridges calls from chromium's c++ world to the objc
+// download_shelf_controller for the shelf (this file). The shelf's background
+// is drawn by download_shelf_view. Every item in a shelf is controlled by a
+// download_item_controller.
+//
+// download_item_mac bridges calls from chromium's c++ world to the objc
+// download_item_controller, which is responsible for managing a single item
+// on the shelf. The item controller loads its UI from a xib file, where the
+// UI of an item itself is represented by a button that is drawn by
+// download_item_cell.
@interface DownloadShelfController : NSViewController {
@private
+ IBOutlet NSScrollView* linkContainer_;
IBOutlet NSTextView* showAllDownloadsLink_;
+ IBOutlet NSImageView* image_;
+
// Currently these two are always the same, but they mean slightly different
// things. |contentAreaHasOffset_| is an implementation detail of the download
// shelf visibility.
@@ -27,11 +45,14 @@ class DownloadShelf;
BOOL barIsVisible_;
scoped_ptr<DownloadShelf> bridge_;
- NSView* contentArea_;
+ NSView* contentArea_; // the browser's content area
float shelfHeight_;
// The download items we have added to our shelf.
scoped_nsobject<NSMutableArray> downloadItemControllers_;
+
+ // The container that contains (and clamps) all the download items.
+ IBOutlet NSView* itemContainerView_;
};
- (id)initWithBrowser:(Browser*)browser contentArea:(NSView*)content;
diff --git a/chrome/browser/cocoa/download_shelf_controller.mm b/chrome/browser/cocoa/download_shelf_controller.mm
index ccb672d..0cb170a 100644
--- a/chrome/browser/cocoa/download_shelf_controller.mm
+++ b/chrome/browser/cocoa/download_shelf_controller.mm
@@ -17,6 +17,10 @@
namespace {
+// Max number of download views we'll contain. Any time a view is added and
+// we already have this many download views, one is removed.
+const size_t kMaxDownloadItemCount = 16;
+
// Border padding of a download item.
const int kDownloadItemBorderPadding = 3;
@@ -38,6 +42,7 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
- (void)applyContentAreaOffset:(BOOL)apply;
- (void)positionBar;
- (void)showDownloadShelf:(BOOL)enable;
+- (void)resizeDownloadLinkToFit;
@end
@@ -81,6 +86,47 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
[[showAllDownloadsLink_ textStorage] setAttributedString:linkText.get()];
[showAllDownloadsLink_ setDelegate:self];
+
+ [self resizeDownloadLinkToFit];
+}
+
+- (void)dealloc {
+ for (DownloadItemController* itemController
+ in downloadItemControllers_.get()) {
+ [[NSNotificationCenter defaultCenter] removeObserver:itemController];
+ }
+ [super dealloc];
+}
+
+- (void)resizeDownloadLinkToFit {
+ // Get width required by localized download link text.
+ // http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html
+ [[showAllDownloadsLink_ textContainer] setLineFragmentPadding:0.0];
+ (void)[[showAllDownloadsLink_ layoutManager]glyphRangeForTextContainer:
+ [showAllDownloadsLink_ textContainer]];
+ NSRect textRect = [[showAllDownloadsLink_ layoutManager]
+ usedRectForTextContainer:[showAllDownloadsLink_ textContainer]];
+
+ int offsetX = [showAllDownloadsLink_ frame].size.width - textRect.size.width;
+
+ // Fit link itself.
+ NSRect linkFrame = [linkContainer_ frame];
+ linkFrame.origin.x += offsetX;
+ linkFrame.size.width -= offsetX;
+ [linkContainer_ setFrame:linkFrame];
+ [linkContainer_ setNeedsDisplay:YES];
+
+ // Move image.
+ NSRect imageFrame = [image_ frame];
+ imageFrame.origin.x += offsetX;
+ [image_ setFrame:imageFrame];
+ [image_ setNeedsDisplay:YES];
+
+ // Change item container size.
+ NSRect itemFrame = [itemContainerView_ frame];
+ itemFrame.size.width += offsetX;
+ [itemContainerView_ setFrame:itemFrame];
+ [itemContainerView_ setNeedsDisplay:YES];
}
- (BOOL)textView:(NSTextView *)aTextView
@@ -115,9 +161,13 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
// explicity release it so that it removes itself as an Observer of the
// DownloadItem. We don't want to wait for autorelease since the DownloadItem
// we are observing will likely be gone by then.
+ [[NSNotificationCenter defaultCenter] removeObserver:download];
[[download view] removeFromSuperview];
[downloadItemControllers_ removeObject:download];
+ // TODO(thakis): Need to relayout the remaining item views here (
+ // crbug.com/17831 ).
+
// Check to see if we have any downloads remaining and if not, hide the shelf.
if (![downloadItemControllers_ count])
[self showDownloadShelf:NO];
@@ -195,17 +245,16 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
// TODO(thakis): RTL support?
// (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
// Shift all existing items to the right
- for (DownloadItemController* itemController in downloadItemControllers_.get()) {
+ for (DownloadItemController* itemController
+ in downloadItemControllers_.get()) {
NSRect frame = [[itemController view] frame];
frame.origin.x += kDownloadItemWidth + kDownloadItemPadding;
[[[itemController view] animator] setFrame:frame];
}
- // Insert new item at the left
- int startX = kDownloadItemBorderPadding;
-
+ // Insert new item at the left.
// Start at width 0...
- NSRect position = NSMakeRect(startX, kDownloadItemBorderPadding,
+ NSRect position = NSMakeRect(0, kDownloadItemBorderPadding,
0, kDownloadItemHeight);
scoped_nsobject<DownloadItemController> controller(
[[DownloadItemController alloc] initWithFrame:position
@@ -213,7 +262,18 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
shelf:self]);
[downloadItemControllers_ addObject:controller.get()];
- [[self view] addSubview:[controller.get() view]];
+ [itemContainerView_ addSubview:[controller.get() view]];
+
+ [[NSNotificationCenter defaultCenter]
+ addObserver:controller
+ selector:@selector(updateVisibility:)
+ name:NSViewFrameDidChangeNotification
+ object:[controller view]];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:controller
+ selector:@selector(updateVisibility:)
+ name:NSViewFrameDidChangeNotification
+ object:itemContainerView_];
// ...then animate in
NSRect frame = [[controller.get() view] frame];
@@ -223,6 +283,16 @@ const NSTimeInterval kDownloadItemOpenDuration = 0.8;
[[NSAnimationContext currentContext] setDuration:kDownloadItemOpenDuration];
[[[controller.get() view] animator] setFrame:frame];
[NSAnimationContext endGrouping];
+
+ // Keep only a limited number of items in the shelf.
+ if ([downloadItemControllers_ count] > kMaxDownloadItemCount) {
+ DCHECK(kMaxDownloadItemCount > 0);
+
+ // Since no user will ever see the item being removed (needs a horizontal
+ // screen resolution greater than 3200 at 16 items at 200 pixels each),
+ // there's no point in animating the removal.
+ [self remove:[downloadItemControllers_ objectAtIndex:0]];
+ }
}
@end
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index c353740..49a778e 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2686,6 +2686,7 @@
'app/theme/close_bar.pdf',
'app/theme/close_bar_h.pdf',
'app/theme/close_bar_p.pdf',
+ 'app/theme/downloads_favicon.png',
'app/theme/forward_Template.pdf',
'app/theme/frozen_tab.png',
'app/theme/go_Template.pdf',