diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 03:26:13 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 03:26:13 +0000 |
commit | 15be81387f3ab40242d28f3ee53adc3d6a1fac1c (patch) | |
tree | 85ec956d20e07971d630aa1920eacdf73401347b /chrome | |
parent | 969a7b97029963ba6c6dd1456132d844160b5ad0 (diff) | |
download | chromium_src-15be81387f3ab40242d28f3ee53adc3d6a1fac1c.zip chromium_src-15be81387f3ab40242d28f3ee53adc3d6a1fac1c.tar.gz chromium_src-15be81387f3ab40242d28f3ee53adc3d6a1fac1c.tar.bz2 |
Mac: Add favicons to task manager.
Pull NSImage cache out of search engine dialog into its own class, reuse that.
Implement browser icon code in task_manager_resource_provider's browser resource provider.
BUG=13156
TEST=Open task manager. You should see icons. Open search engine manager, should still show icons.
Review URL: http://codereview.chromium.org/549021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser.cc | 4 | ||||
-rw-r--r-- | chrome/browser/cocoa/keyword_editor_cocoa_controller.h | 14 | ||||
-rw-r--r-- | chrome/browser/cocoa/keyword_editor_cocoa_controller.mm | 62 | ||||
-rw-r--r-- | chrome/browser/cocoa/table_row_nsimage_cache.h | 50 | ||||
-rw-r--r-- | chrome/browser/cocoa/table_row_nsimage_cache.mm | 78 | ||||
-rw-r--r-- | chrome/browser/cocoa/table_row_nsimage_cache_unittest.mm | 61 | ||||
-rw-r--r-- | chrome/browser/cocoa/task_manager_mac.h | 14 | ||||
-rw-r--r-- | chrome/browser/cocoa/task_manager_mac.mm | 55 | ||||
-rw-r--r-- | chrome/browser/task_manager_resource_providers.cc | 10 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 | ||||
-rwxr-xr-x | chrome/chrome_tests.gypi | 1 |
11 files changed, 290 insertions, 61 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 91f0101..6a0ba3e 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -2557,9 +2557,9 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, true); // TODO(viettrungluu): Temporarily disabled on Mac. Must disable here (not in // BWC) so that it also affects the page menu. http://crbug.com/13156 -#if !defined(OS_MACOSX) +//#if !defined(OS_MACOSX) command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true); -#endif +//#endif command_updater_.UpdateCommandEnabled(IDC_SELECT_PROFILE, true); command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true); command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER, true); diff --git a/chrome/browser/cocoa/keyword_editor_cocoa_controller.h b/chrome/browser/cocoa/keyword_editor_cocoa_controller.h index 5e84426..9023a15 100644 --- a/chrome/browser/cocoa/keyword_editor_cocoa_controller.h +++ b/chrome/browser/cocoa/keyword_editor_cocoa_controller.h @@ -7,6 +7,7 @@ #include "app/table_model_observer.h" #import "base/cocoa_protocols_mac.h" #include "base/scoped_ptr.h" +#include "chrome/browser/cocoa/table_row_nsimage_cache.h" #include "chrome/browser/search_engines/edit_search_engine_controller.h" #include "chrome/browser/search_engines/keyword_editor_controller.h" #include "chrome/browser/search_engines/template_url_model.h" @@ -18,7 +19,8 @@ class Profile; // Very thin bridge that simply pushes notifications from C++ to ObjC. class KeywordEditorModelObserver : public TemplateURLModelObserver, public EditSearchEngineControllerDelegate, - public TableModelObserver { + public TableModelObserver, + public TableRowNSImageCache::Table { public: explicit KeywordEditorModelObserver(KeywordEditorCocoaController* controller); virtual ~KeywordEditorModelObserver(); @@ -42,15 +44,17 @@ class KeywordEditorModelObserver : public TemplateURLModelObserver, virtual void OnItemsAdded(int start, int length); virtual void OnItemsRemoved(int start, int length); - // Lazily converts the image at the given row and caches it in |iconImages_|. + // TableRowNSImageCache::Table + virtual int RowCount() const; + virtual SkBitmap GetIcon(int row) const; + + // Lazily converts the image at the given row and caches it in |icon_cache_|. NSImage* GetImageForRow(int row); private: KeywordEditorCocoaController* controller_; - // Stores strong NSImage refs for icons. If an entry is NULL, it will be - // created in GetImageForRow(). - scoped_nsobject<NSPointerArray> iconImages_; + TableRowNSImageCache icon_cache_; DISALLOW_COPY_AND_ASSIGN(KeywordEditorModelObserver); }; diff --git a/chrome/browser/cocoa/keyword_editor_cocoa_controller.mm b/chrome/browser/cocoa/keyword_editor_cocoa_controller.mm index d2e1d7a..7440a17 100644 --- a/chrome/browser/cocoa/keyword_editor_cocoa_controller.mm +++ b/chrome/browser/cocoa/keyword_editor_cocoa_controller.mm @@ -30,11 +30,7 @@ KeywordEditorModelObserver::KeywordEditorModelObserver( KeywordEditorCocoaController* controller) : controller_(controller), - iconImages_([[NSPointerArray alloc] initWithOptions: - NSPointerFunctionsStrongMemory | - NSPointerFunctionsObjectPersonality]) { - int count = [controller_ controller]->table_model()->RowCount(); - [iconImages_ setCount:count]; + icon_cache_(this) { } KeywordEditorModelObserver::~KeywordEditorModelObserver() { @@ -59,65 +55,35 @@ void KeywordEditorModelObserver::OnEditedKeyword( } void KeywordEditorModelObserver::OnModelChanged() { - int count = [controller_ controller]->table_model()->RowCount(); - [iconImages_ setCount:0]; - [iconImages_ setCount:count]; + icon_cache_.OnModelChanged(); [controller_ modelChanged]; } void KeywordEditorModelObserver::OnItemsChanged(int start, int length) { - DCHECK_LE(start + length, static_cast<int>([iconImages_ count])); - for (int i = start; i < (start + length); ++i) { - [iconImages_ replacePointerAtIndex:i withPointer:NULL]; - } - DCHECK_EQ([controller_ controller]->table_model()->RowCount(), - static_cast<int>([iconImages_ count])); + icon_cache_.OnItemsChanged(start, length); [controller_ modelChanged]; } void KeywordEditorModelObserver::OnItemsAdded(int start, int length) { - DCHECK_LE(start, static_cast<int>([iconImages_ count])); - - // -[NSPointerArray insertPointer:atIndex:] throws if index == count. - // Instead expand the array with NULLs. - if (start == static_cast<int>([iconImages_ count])) { - [iconImages_ setCount:start + length]; - } else { - for (int i = 0; i < length; ++i) { - [iconImages_ insertPointer:NULL atIndex:start]; // Values slide up. - } - } - DCHECK_EQ([controller_ controller]->table_model()->RowCount(), - static_cast<int>([iconImages_ count])); + icon_cache_.OnItemsAdded(start, length); [controller_ modelChanged]; } void KeywordEditorModelObserver::OnItemsRemoved(int start, int length) { - DCHECK_LE(start + length, static_cast<int>([iconImages_ count])); - for (int i = 0; i < length; ++i) { - [iconImages_ removePointerAtIndex:start]; // Values slide down. - } - DCHECK_EQ([controller_ controller]->table_model()->RowCount(), - static_cast<int>([iconImages_ count])); + icon_cache_.OnItemsRemoved(start, length); [controller_ modelChanged]; } +int KeywordEditorModelObserver::RowCount() const { + return [controller_ controller]->table_model()->RowCount(); +} + +SkBitmap KeywordEditorModelObserver::GetIcon(int row) const { + return [controller_ controller]->table_model()->GetIcon(row); +} + NSImage* KeywordEditorModelObserver::GetImageForRow(int row) { - DCHECK_EQ([controller_ controller]->table_model()->RowCount(), - static_cast<int>([iconImages_ count])); - DCHECK_GE(row, 0); - DCHECK_LT(row, static_cast<int>([iconImages_ count])); - NSImage* image = static_cast<NSImage*>([iconImages_ pointerAtIndex:row]); - if (!image) { - const SkBitmap bitmapIcon = - [controller_ controller]->table_model()->GetIcon(row); - if (!bitmapIcon.isNull()) { - image = gfx::SkBitmapToNSImage(bitmapIcon); - DCHECK(image); - [iconImages_ replacePointerAtIndex:row withPointer:image]; - } - } - return image; + return icon_cache_.GetImageForRow(row); } // KeywordEditorCocoaController ----------------------------------------------- diff --git a/chrome/browser/cocoa/table_row_nsimage_cache.h b/chrome/browser/cocoa/table_row_nsimage_cache.h new file mode 100644 index 0000000..04ca13e --- /dev/null +++ b/chrome/browser/cocoa/table_row_nsimage_cache.h @@ -0,0 +1,50 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_TABLE_ROW_NSIMAGE_CACHE_H_ +#define CHROME_BROWSER_COCOA_TABLE_ROW_NSIMAGE_CACHE_H_ + +#import <Cocoa/Cocoa.h> + +#include "base/scoped_nsobject.h" +#include "third_party/skia/include/core/SkBitmap.h" + +// There are several dialogs that display tabular data with one SkBitmap +// per row. This class converts these SkBitmaps to NSImages on demand, and +// caches the results. +class TableRowNSImageCache { + public: + // Interface this cache expects for its table model. + class Table { + public: + // Returns the number of rows in the table. + virtual int RowCount() const = 0; + + // Returns the icon of the |row|th row. + virtual SkBitmap GetIcon(int row) const = 0; + }; + + // |model| must outlive the cache. + explicit TableRowNSImageCache(Table* model); + + // Lazily converts the image at the given row and caches it in |icon_images_|. + NSImage* GetImageForRow(int row); + + // Call these functions every time the table changes, to update the cache. + void OnModelChanged(); + void OnItemsChanged(int start, int length); + void OnItemsAdded(int start, int length); + void OnItemsRemoved(int start, int length); + + private: + // The table model we query for row count and icons. + Table* model_; // weak + + // Stores strong NSImage refs for icons. If an entry is NULL, it will be + // created in GetImageForRow(). + scoped_nsobject<NSPointerArray> icon_images_; +}; + +#endif // CHROME_BROWSER_COCOA_TABLE_ROW_NSIMAGE_CACHE_H_ + diff --git a/chrome/browser/cocoa/table_row_nsimage_cache.mm b/chrome/browser/cocoa/table_row_nsimage_cache.mm new file mode 100644 index 0000000..e8ddab3 --- /dev/null +++ b/chrome/browser/cocoa/table_row_nsimage_cache.mm @@ -0,0 +1,78 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/cocoa/table_row_nsimage_cache.h" + +#include "base/logging.h" +#include "skia/ext/skia_utils_mac.h" + +TableRowNSImageCache::TableRowNSImageCache(Table* model) + : model_(model), + icon_images_([[NSPointerArray alloc] initWithOptions: + NSPointerFunctionsStrongMemory | + NSPointerFunctionsObjectPersonality]) { + int count = model_->RowCount(); + [icon_images_ setCount:count]; +} + +void TableRowNSImageCache::OnModelChanged() { + int count = model_->RowCount(); + [icon_images_ setCount:0]; + [icon_images_ setCount:count]; +} + +void TableRowNSImageCache::OnItemsChanged(int start, int length) { + DCHECK_LE(start + length, static_cast<int>([icon_images_ count])); + for (int i = start; i < (start + length); ++i) { + [icon_images_ replacePointerAtIndex:i withPointer:NULL]; + } + DCHECK_EQ(model_->RowCount(), + static_cast<int>([icon_images_ count])); +} + +void TableRowNSImageCache::OnItemsAdded(int start, int length) { + DCHECK_LE(start, static_cast<int>([icon_images_ count])); + + // -[NSPointerArray insertPointer:atIndex:] throws if index == count. + // Instead expand the array with NULLs. + if (start == static_cast<int>([icon_images_ count])) { + [icon_images_ setCount:start + length]; + } else { + for (int i = 0; i < length; ++i) { + [icon_images_ insertPointer:NULL atIndex:start]; // Values slide up. + } + } + DCHECK_EQ(model_->RowCount(), + static_cast<int>([icon_images_ count])); +} + +void TableRowNSImageCache::OnItemsRemoved(int start, int length) { + DCHECK_LE(start + length, static_cast<int>([icon_images_ count])); + for (int i = 0; i < length; ++i) { + [icon_images_ removePointerAtIndex:start]; // Values slide down. + } + DCHECK_EQ(model_->RowCount(), + static_cast<int>([icon_images_ count])); +} + +NSImage* TableRowNSImageCache::GetImageForRow(int row) { + DCHECK_EQ(model_->RowCount(), + static_cast<int>([icon_images_ count])); + DCHECK_GE(row, 0); + DCHECK_LT(row, static_cast<int>([icon_images_ count])); + NSImage* image = static_cast<NSImage*>([icon_images_ pointerAtIndex:row]); + if (!image) { + const SkBitmap bitmap_icon = + model_->GetIcon(row); + // This means GetIcon() will get called until it returns a non-empty bitmap. + // Empty bitmaps are intentionally not cached. + if (!bitmap_icon.isNull()) { + image = gfx::SkBitmapToNSImage(bitmap_icon); + DCHECK(image); + [icon_images_ replacePointerAtIndex:row withPointer:image]; + } + } + return image; +} + diff --git a/chrome/browser/cocoa/table_row_nsimage_cache_unittest.mm b/chrome/browser/cocoa/table_row_nsimage_cache_unittest.mm new file mode 100644 index 0000000..975c065 --- /dev/null +++ b/chrome/browser/cocoa/table_row_nsimage_cache_unittest.mm @@ -0,0 +1,61 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/cocoa/table_row_nsimage_cache.h" + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using ::testing::Return; + +class MockTable : public TableRowNSImageCache::Table { + public: + MOCK_CONST_METHOD0(RowCount, int()); + MOCK_CONST_METHOD1(GetIcon, SkBitmap(int)); +}; + +TEST(TableRowNSImageCacheTest, Basics) { + SkBitmap first_bitmap; + first_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 40, 30); + first_bitmap.eraseRGB(255, 0, 0); + ASSERT_TRUE(first_bitmap.allocPixels()); + + SkBitmap second_bitmap; + second_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 20, 10); + second_bitmap.eraseRGB(0, 255, 0); + ASSERT_TRUE(second_bitmap.allocPixels()); + + MockTable table; + + EXPECT_CALL(table, RowCount()).WillRepeatedly(Return(2)); + TableRowNSImageCache cache(&table); + + // Check both images are only generated once + EXPECT_CALL(table, GetIcon(0)).WillOnce(Return(first_bitmap)); + NSImage* first_image = cache.GetImageForRow(0); + EXPECT_EQ(40, [first_image size].width); + EXPECT_EQ(30, [first_image size].height); + EXPECT_EQ(first_image, cache.GetImageForRow(0)); + + EXPECT_CALL(table, GetIcon(1)).WillOnce(Return(second_bitmap)); + NSImage* second_image = cache.GetImageForRow(1); + EXPECT_EQ(20, [second_image size].width); + EXPECT_EQ(10, [second_image size].height); + EXPECT_EQ(second_image, cache.GetImageForRow(1)); + + // Check that invalidating the second icon only invalidates the second icon + cache.OnItemsChanged(/* start =*/1, /* length =*/1); + EXPECT_EQ(first_image, cache.GetImageForRow(0)); + + EXPECT_CALL(table, GetIcon(1)).WillOnce(Return(first_bitmap)); + NSImage* new_second_image = cache.GetImageForRow(1); + EXPECT_EQ(40, [new_second_image size].width); + EXPECT_EQ(30, [new_second_image size].height); + EXPECT_EQ(new_second_image, cache.GetImageForRow(1)); + EXPECT_NE(new_second_image, second_image); +} + +} // namespace diff --git a/chrome/browser/cocoa/task_manager_mac.h b/chrome/browser/cocoa/task_manager_mac.h index cbcb5d2..5d78cff 100644 --- a/chrome/browser/cocoa/task_manager_mac.h +++ b/chrome/browser/cocoa/task_manager_mac.h @@ -7,6 +7,7 @@ #import <Cocoa/Cocoa.h> #include "base/scoped_nsobject.h" +#include "chrome/browser/cocoa/table_row_nsimage_cache.h" #include "chrome/browser/task_manager.h" class TaskManagerMac; @@ -39,7 +40,8 @@ class TaskManagerMac; @end // This class listens to task changed events sent by chrome. -class TaskManagerMac : public TaskManagerModelObserver { +class TaskManagerMac : public TaskManagerModelObserver, + public TableRowNSImageCache::Table { public: TaskManagerMac(); virtual ~TaskManagerMac(); @@ -54,6 +56,10 @@ class TaskManagerMac : public TaskManagerModelObserver { // controller destroyed itself. Informs the model to stop updating. void WindowWasClosed(); + // TableRowNSImageCache::Table + virtual int RowCount() const { return model_->ResourceCount(); } + virtual SkBitmap GetIcon(int r) const { return model_->GetResourceIcon(r); } + // Creates the task manager if it doesn't exist; otherwise, it activates the // existing task manager window. static void Show(); @@ -61,6 +67,9 @@ class TaskManagerMac : public TaskManagerModelObserver { // Returns the TaskManager observed by |this|. TaskManager* task_manager() { return task_manager_; } + // Lazily converts the image at the given row and caches it in |icon_cache_|. + NSImage* GetImageForRow(int row); + private: // The task manager. TaskManager* const task_manager_; // weak @@ -72,6 +81,9 @@ class TaskManagerMac : public TaskManagerModelObserver { // is closed. TaskManagerWindowController* window_controller_; // weak + // Caches favicons for all rows. Needs to be initalized after |model_|. + TableRowNSImageCache icon_cache_; + // An open task manager window. There can only be one open at a time. This // is reset to NULL when the window is closed. static TaskManagerMac* instance_; diff --git a/chrome/browser/cocoa/task_manager_mac.mm b/chrome/browser/cocoa/task_manager_mac.mm index 71b24f5..91e8f92 100644 --- a/chrome/browser/cocoa/task_manager_mac.mm +++ b/chrome/browser/cocoa/task_manager_mac.mm @@ -13,13 +13,13 @@ #include "grit/generated_resources.h" // TODO(thakis): Autoremember window size/pos (and selected columns?) +// TODO(thakis): Better resizing behavior (and think about storing column sizes) // TODO(thakis): Column sort comparator // TODO(thakis): Clicking column header doesn't sort -// TODO(thakis): Favicons in rows // TODO(thakis): Default sort column @interface TaskManagerWindowController (Private) -- (void)addColumnWithId:(int)columnId visible:(BOOL)isVisible; +- (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible; - (void)setUpTableColumns; - (void)setUpTableHeaderContextMenu; - (void)toggleColumn:(id)sender; @@ -79,7 +79,7 @@ // Adds a column which has the given string id as title. |isVisible| specifies // if the column is initially visible. -- (void)addColumnWithId:(int)columnId visible:(BOOL)isVisible { +- (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible { scoped_nsobject<NSTableColumn> column([[NSTableColumn alloc] initWithIdentifier:[NSNumber numberWithInt:columnId]]); @@ -94,13 +94,23 @@ [column.get() setHidden:!isVisible]; [column.get() setEditable:NO]; [tableView_ addTableColumn:column.get()]; + return column.get(); // Now retained by |tableView_|. } // Adds all the task manager's columns to the table. - (void)setUpTableColumns { for (NSTableColumn* column in [tableView_ tableColumns]) [tableView_ removeTableColumn:column]; - [self addColumnWithId:IDS_TASK_MANAGER_PAGE_COLUMN visible:YES]; + NSTableColumn* nameColumn = [self addColumnWithId:IDS_TASK_MANAGER_PAGE_COLUMN + visible:YES]; + // |nameColumn| displays an icon for every row -- this is done by an + // NSButtonCell. + scoped_nsobject<NSButtonCell> nameCell( + [[NSButtonCell alloc] initTextCell:@""]); + [nameCell.get() setImagePosition:NSImageLeft]; + [nameCell.get() setButtonType:NSSwitchButton]; + [nameColumn setDataCell:nameCell.get()]; + [self addColumnWithId:IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN visible:YES]; [self addColumnWithId:IDS_TASK_MANAGER_SHARED_MEM_COLUMN visible:NO]; [self addColumnWithId:IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN visible:NO]; @@ -257,10 +267,36 @@ - (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)rowIndex { + // NSButtonCells expect an on/off state as objectValue. Their title is set + // in |tableView:dataCellForTableColumn:row:| below. + if ([[tableColumn identifier] intValue] == IDS_TASK_MANAGER_PAGE_COLUMN) { + return [NSNumber numberWithInt:NSOffState]; + } + return [self modelTextForRow:rowIndex column:[[tableColumn identifier] intValue]]; } +- (NSCell*)tableView:(NSTableView*)tableView + dataCellForTableColumn:(NSTableColumn*)tableColumn + row:(NSInteger)rowIndex { + NSCell* cell = [tableColumn dataCellForRow:rowIndex]; + + // Set the favicon and title for the search engine in the name column. + if ([[tableColumn identifier] intValue] == IDS_TASK_MANAGER_PAGE_COLUMN) { + DCHECK([cell isKindOfClass:[NSButtonCell class]]); + NSButtonCell* buttonCell = static_cast<NSButtonCell*>(cell); + NSString* title = [self modelTextForRow:rowIndex + column:[[tableColumn identifier] intValue]]; + [buttonCell setTitle:title]; + [buttonCell setImage:taskManagerObserver_->GetImageForRow(rowIndex)]; + [buttonCell setRefusesFirstResponder:YES]; // Don't push in like a button. + [buttonCell setHighlightsBy:NSNoCellMask]; + } + + return cell; +} + @end //////////////////////////////////////////////////////////////////////////////// @@ -268,7 +304,8 @@ TaskManagerMac::TaskManagerMac() : task_manager_(TaskManager::GetInstance()), - model_(TaskManager::GetInstance()->model()) { + model_(TaskManager::GetInstance()->model()), + icon_cache_(this) { window_controller_ = [[TaskManagerWindowController alloc] initWithTaskManagerObserver:this]; model_->AddObserver(this); @@ -286,21 +323,29 @@ TaskManagerMac::~TaskManagerMac() { // TaskManagerMac, TaskManagerModelObserver implementation: void TaskManagerMac::OnModelChanged() { + icon_cache_.OnModelChanged(); [window_controller_ reloadData]; } void TaskManagerMac::OnItemsChanged(int start, int length) { + icon_cache_.OnItemsChanged(start, length); [window_controller_ reloadData]; } void TaskManagerMac::OnItemsAdded(int start, int length) { + icon_cache_.OnItemsAdded(start, length); [window_controller_ reloadData]; } void TaskManagerMac::OnItemsRemoved(int start, int length) { + icon_cache_.OnItemsRemoved(start, length); [window_controller_ reloadData]; } +NSImage* TaskManagerMac::GetImageForRow(int row) { + return icon_cache_.GetImageForRow(row); +} + //////////////////////////////////////////////////////////////////////////////// // TaskManagerMac, public: diff --git a/chrome/browser/task_manager_resource_providers.cc b/chrome/browser/task_manager_resource_providers.cc index 715dd08..57f6b7a 100644 --- a/chrome/browser/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager_resource_providers.cc @@ -40,6 +40,10 @@ #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#if defined(OS_MACOSX) +#include "skia/ext/skia_utils_mac.h" +#endif + //////////////////////////////////////////////////////////////////////////////// // TaskManagerTabContentsResource class //////////////////////////////////////////////////////////////////////////////// @@ -711,6 +715,12 @@ TaskManagerBrowserProcessResource::TaskManagerBrowserProcessResource() ResourceBundle& rb = ResourceBundle::GetSharedInstance(); default_icon_ = rb.GetBitmapNamed(IDR_PRODUCT_LOGO_16); } +#elif defined(OS_MACOSX) + if (!default_icon_) { + // IDR_PRODUCT_LOGO_16 doesn't quite look like chrome/mac's icns icon. Load + // the real app icon (requires a nsimage->skbitmap->nsimage conversion :-(). + default_icon_ = new SkBitmap(gfx::AppplicationIconAtSize(16)); + } #else // TODO(port): Port icon code. NOTIMPLEMENTED(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2625ca9..ce9f93f 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -561,6 +561,8 @@ 'browser/cocoa/tab_view.mm', 'browser/cocoa/tab_window_controller.h', 'browser/cocoa/tab_window_controller.mm', + 'browser/cocoa/table_row_nsimage_cache.h', + 'browser/cocoa/table_row_nsimage_cache.mm', 'browser/cocoa/task_manager_mac.h', 'browser/cocoa/task_manager_mac.mm', 'browser/cocoa/theme_install_bubble_view.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index d00af61..fc55fe3 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -653,6 +653,7 @@ 'browser/cocoa/tab_strip_controller_unittest.mm', 'browser/cocoa/tab_strip_view_unittest.mm', 'browser/cocoa/tab_view_unittest.mm', + 'browser/cocoa/table_row_nsimage_cache_unittest.mm', 'browser/cocoa/task_manager_mac_unittest.mm', 'browser/cocoa/test_event_utils.h', 'browser/cocoa/test_event_utils.mm', |